如何在核心 2 的用户表中保存 IFormFile 类型的属性 asp.net?



在 asp.net 核心 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;}注册视图模型有这个:public IFormFile FileToUpload { get; set; }

任何帮助将不胜感激。

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

简而言之,ApplicationUser在实体框架中的DbContext中作为实体分配。EF Core 通常尝试将实体类的每个属性映射到数据库中的值。EF Core 无法将IFormFile直接映射到数据类型以在数据库中创建列(在这种情况下也不需要这样做(。

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

为了补充 Neville 的回答,我建议您创建一个ApplicationUserViewModel,以便您可以将前端逻辑和输入/验证与您用于数据库的模型域分开,更具体地说,在您获取文件协定ApplicationUserViewModelIFormFile,在前一个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,而是具有对它的引用,这比每次实例化 Blob 时都必须下载 Blob 的性能更高ApplicationUser

最新更新