如何处理Razor页面中的input = file/IFormFile双向绑定 [英] How to deal with input=file / IFormFile two-way binding in Razor Pages

查看:203
本文介绍了如何处理Razor页面中的input = file/IFormFile双向绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有byte []的实体,用于将徽标作为varbinary存储在数据库中.但是,要在Razor Page上使用此模型,我已经对其进行了扩展,并添加了IFormFile属性以接收上载的文件.

I have an entity that has byte[] to store logos in the database as varbinary. But to use this model on a Razor Page, I have extended it and added a IFormFile property to receive the uploaded file.

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:

And in a method I fetch this company from the database and set IFormFile accordingly:

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 Page

And the UploadedLogo is populated and I bind that on Razor Page

<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 作为文件上传插件和

By the way, I am using Dropify as file upload plugin and jquery-ajax-unobtrusive library to handle post requests. Here is the post method:

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;
}

现在是这种情况:

  • When I am adding a new company, I enter company name and browse a file from my computer, and save the data. I can see Uploaded logo in company model received in post request, which is then converted to byte[] and saved in database. Everything is fine. Below is the fiddler capture: Fiddler capture for INSERT
  • Problem starts when I try to edit the company. I open the company, service fetches the data, convert byte[] to IFormFile and the data (name + logo) is shown on the form. I just edit the name, do not touch the logo and let it be as it is and hit save. At this point, the Uploaded logo is null in company model received in post request. Below is the fiddler capture: Fiddler capture for UPDATE

我可以清楚地看到已发布请求中的差异.如果是编辑,则文件不存在.但是我不知道该如何解决.那天是我为此伤脑筋,有人可以帮我吗?

I can see the difference in the posted requests captures clearly. The file is not there in the case of edit. But I don't know how to fix this. It has been a day I am hurting my brain on this, can anyone assist me on this please?

更新:还添加了提琴手捕获.

UPDATE: Added fiddler captures as well.

推荐答案

我知道这不是最好的解决方案,但我设法做到了.

I know this is not the best solution, but I managed to work it.

我所做的是,我将图像字节转换为图像的base64 data-uri,并将uri保存在input [hidden]中.我还添加了另一个输入[hidden],以保存有关用户是否更改徽标的标志.当用户更改徽标时,我使用上传的图片和flag = true的新base64 data-uri更新这些隐藏的字段.如果用户不更改图像,则uri相同且flag = false.现在保存,我得到了uri字符串和标志.如果该标记为true,则将uri转换为图像并将其保存在数据库中.

What I did is, I converted the image bytes into base64 data-uri of the image and save the uri in an input[hidden]. I also added another input[hidden] to save the flag that whether the user has changed the logo or not. And when the user changes the logo, I update these hidden fields with the new base64 data-uri of uploaded image and flag=true. And if the user does not change the image, the uri is the same and flag=false. Now on save, I get the uri string and the flag. If the flag is true, I convert the uri into the image and persist it in the database.

这篇关于如何处理Razor页面中的input = file/IFormFile双向绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆