我有一个实体,它具有 byte[] 将徽标作为 varbinary 存储在数据库中。但为了在 Razor 页面上使用此模型,我对其进行了扩展并添加了 IFormFile 属性来接收上传的文件。
public class Company
{
public string Name { get; set; }
public byte[] Logo { get; set; }
}
public class CompanyModel : Company
{
[DataType(DataType.Upload)]
[FromForm(Name = "UploadedLogo")]
public IFormFile UploadedLogo { get; set; }
}
在一种方法中,我从数据库中获取该公司并相应地设置 IFormFile:
var response = await _companyService.GetByIdAsync(id);
if (response != null)
{
if (response.Logo != null)
{
using (var stream = new MemoryStream(response.Logo))
{
var formFile = new FormFile(stream, 0, stream.Length, response.Name, response.Name);
formFile.Headers = new HeaderDictionary()
{
new KeyValuePair<string, StringValues>("Content-Disposition", $"form-data; name=\"Company.UploadedLogo\"; filename=\"{response.Name}.png\""),
new KeyValuePair<string, StringValues>("Content-Type", "image/png"),
};
response.UploadedLogo = formFile;
}
}
return response;
}
UploadedLogo 已填充,我将其绑定到 Razor 页面上
<form method="post"
enctype="multipart/form-data"
data-ajax="true"
data-ajax-method="post"
data-ajax-begin="begin"
data-ajax-complete="completed"
data-ajax-failure="failed">
...
<div class="form-group row">
<div class="col-sm-2 text-right">
<label asp-for="@Model.Company.Logo" class="col-form-label"></label>
</div>
<div class="col-sm-9">
<input type="file" class="dropify" data-height="200"
asp-for="@Model.Company.UploadedLogo"
data-max-file-size="100K" data-allowed-file-extensions="png jpg jpeg" />
</div>
</div>
...
<div class="form-group modal-actions">
<input type="submit" class="btn btn-primary btn-icon-text btn-md btn-save-editing" value="Save" />
</div>
</form>
顺便说一句,我正在使用Dropify https://github.com/JeremyFagis/dropify作为文件上传插件和jquery-ajax-不显眼 https://github.com/aspnet/jquery-ajax-unobtrusive库来处理帖子请求。这是post方法:
public async Task<CompanyModel> OnPostAsync(CompanyModel company)
{
CompanyModel result = new CompanyModel();
try
{
if (company.UploadedLogo != null)
company.Logo = await company.UploadedLogo.GetBytes();
var response = await _companyService.SaveAsync(company);
if (response != null)
result = response;
}
catch (Exception ex)
{
_Logger.LogException(ex);
}
return result;
}
现在是这样的场景:
- 当我添加新公司时,我输入公司名称并从计算机浏览文件,然后保存数据。我可以看到在发布请求中收到的公司模型中上传的徽标,然后将其转换为 byte[] 并保存在数据库中。一切安好。下面是 fiddler 捕获的内容:Fiddler 捕获 INSERT https://i.stack.imgur.com/WRHln.png
-
问题开始当我尝试编辑公司时。我打开公司,服务获取数据,将 byte[] 转换为 IFormFile,数据(名称 + 徽标)显示在表单上。我只是编辑名称,不碰徽标,让它保持原样,然后点击“保存”。此时,在发布请求中收到的公司模型中,上传的徽标为空。下面是 fiddler 捕获的内容:Fiddler 捕获更新 https://i.stack.imgur.com/scUt4.png
我可以清楚地看到发布的请求捕获的差异。编辑时该文件不存在。但我不知道如何解决这个问题。这一天我为此伤透了脑筋,有人能帮我吗?
UPDATE:还添加了小提琴手捕获。