如何在asp.net core 2的users表中保存IFormFile类型的属性?

时间:2018-05-12 00:05:53

标签: c# asp.net-core-mvc

在asp.net core 2.0 MVC中注册用户后,我希望能够上传pdf文件并将其名称或Id保存在该用户的表行中,以便稍后下载。我做了一切,但我收到了这个错误:

The property 'ApplicationUser.contract' is of an interface type ('IFormFile'). If it is a navigation property manually configure the relationship for this property by casting it to a mapped entity type

我不明白“将它投射到映射的实体类型”是什么意思,我错过了什么?这是我的方法:

首先,上传文件:

   var path = Path.Combine(Directory.GetCurrentDirectory(), "Uploads",model.FileToUpload.GetFilename());


        using (var stream = new FileStream(path, FileMode.Create))
        {
            await model.FileToUpload.CopyToAsync(stream);
        }
然后,将其添加到用户的属性中 var user = new ApplicationUser { UserName = model.username, Email = model.Email, contract = model.FileToUpload };

应用程序用户在模型中有这个:public IFormFile contract {get; set;} 并且registerviewmodel具有:public IFormFile FileToUpload { get; set; }

任何帮助都会非常感激。

2 个答案:

答案 0 :(得分:1)

您的错误消息来自实体框架。您可以在此处阅读有关此内容的完整详细信息:https://docs.microsoft.com/en-us/ef/core/modeling/relationships

简而言之,ApplicationUser在实体框架的DbContext内被指定为实体。 EF Core通常会尝试将实体类的每个属性映射到数据库中的值。 EF Core无法直接将IFormFile映射到数据类型,以便在数据库中创建列(在您的情况下也不需要)。

所以,你的第一步就是告诉EF Core“不要担心这个属性”。这是通过在NotMapped媒体资源上添加IFormFile注释来完成的。下一步是将文件名保存到数据库中以供参考。我注意到您正在使用上传的文件名来执行此操作。为避免名称冲突,您可以使用Guid.NewGuid().ToString()之类的内容生成唯一字符串(不要忘记添加扩展名)。要将此文件名保存到数据库中,您需要在ApplicationUser类中创建字符串属性,仅保存文件名。文件本身不需要进入user对象。

答案 1 :(得分:0)

为了补充Neville的答案,我建议您创建一个ApplicationUserViewModel,这样您就可以将前端逻辑和输入/验证与您用于数据库的模型域分开,更具体地说,在ApplicationUserViewModel您获取文件合约IFormFile,并在之前的ApplicationUser类中创建属性ID,如:

public class ApplicationUser : ...
{
    //... other properties
    [ForeignKey("Contracts")]
    public string ContractId { get; set; }
}

并创建另一个域模型类,如Contracts

public class Contracts
{
    public Guid Id { get; set; }
    public byte[] FileBlob { get; set; }
    public string FileExtension { get; set; }
}

所以在你的实际ApplicationUser中你没有存储整个文件blob但是有一个对它的引用,这导致比每次实例ApplicationUser时下载blob更高的性能