asp.Net   发布时间:2022-04-07  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了asp.net-core – ASP.NET Core 1.1中的multipart / form-data(File JSON)帖子的模型绑定大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试构建一个ASP.NET Core 1.1 Controller方法来处理如下所示的http请求:
POST https://localhost/api/data/upload http/1.1
Content-Type: multipart/form-data; boundary=--------------------------625450203542273177701444
Host: localhost
Content-Length: 474

----------------------------625450203542273177701444
Content-Disposition: form-data; name="file"; filename="myfile.txt"
Content-Type: text/plain

<< Contents of my file >>

----------------------------625450203542273177701444
Content-Disposition: form-data; name="text"
Content-Type: application/json

{"md5":"595f44fec1e92a71d3e9e77456ba80d0","sessionIds":["123","abc"]}
----------------------------625450203542273177701444--

它是一个multipart / form-data请求,其中一部分是(小)文件,另一部分是基于提供的规范的json blob.

理想情况下,我喜欢我的控制器方法看起来像:

[httpPost]
public async Task Post(UploadPayload payload)
{
   // TODO
}

public class UploadPayload
{
    public IFormFile File { get; set; }

    [required]
    [StringLength(32)]
    public String Md5 { get; set; }

    public List<String> SessionIds { get; set; }
}

但唉,这不是Just Work {TM}.当我这样时,IFormFile会填充,但json字符串不会反序列化到其他属性.

我还尝试向UploadPayload添加一个Text属性,该属性具有除IFormFile以外的所有属性,并且也不接收数据.例如.

public class UploadPayload
{
    public IFormFile File { get; set; }

    public UploadPayloadMetadata text { get; set; }
}

public class UploadPayloadMetadata
{
    [required]
    [StringLength(32)]
    public String Md5 { get; set; }

    public List<String> SessionIds { get; set; }
}

我的解决方法是避免模型绑定并使用MultipartReader:

[httpPost]
public async Task Post()
{
   ...

   var reader = new MultipartReader(request.GetMultipartBoundary(),httpContext.request.body);

   var section = await reader.ReadNextSectionAsync();
   var filePart = section.AsFileSection();

   // Do stuff & things with the file

   section = await reader.ReadNextSectionAsync();
   var jsonPart = section.AsFormDataSection();
   var jsonString = await jsonPart.GetValueAsync();

   // Use $JsonLibrary to manually deserailizE into the model
   // Do stuff & things with the metadata

   ...
}

上面的操作绕过了模型验证功能等.另外,我想也许我可以把那个jsonString然后以某种方式让它进入一个状态,然后我可以调用等待TryupdateModelAsync(payloadModel,…)但是无法弄清楚如何到那儿 – 这似乎也没那么干净.

是否有可能像我的第一次尝试一样达到我想要的“透明”模型绑定状态?如果是这样,那怎么会这样呢?

解决方法

这里的第一个问题是数据需要以稍微不同的格式从客户端发送. UploadPayload类中的每个属性都需要以自己的形式发送:
const formData = new FormData();
formData.append(`file`,filE);
formData.append('md5',JSON.Stringify(md5));
formData.append('sessionIds',JSON.Stringify(sessionIds));

执行此操作后,可以将[F​​romForm]属性添加到MD5属性以将其绑定,因为它是一个简单的字符串值.这不适用于SessionIds属性,因为它是一个复杂的对象.

可以使用自定义模型绑定器来完成从表单数据绑定复杂JSON:

public class FormDataJsonBinder : IModelBinder
{
    public Task BindModelAsync(ModelBindingContext bindingContext)
    {
        if(bindingContext == null) throw new ArgumentNullException(nameof(bindingContext));

        // Fetch the value of the argument by name and set it to the model state
        String fieldName = bindingContext.FieldName;
        var valueProviderResult = bindingContext.ValueProvider.GetValue(fieldName);
        if(valueProviderResult == ValueProviderResult.NonE) return Task.CompletedTask;
        else bindingContext.ModelState.SetModelValue(fieldName,valueProviderResult);

        // Do nothing if the value is null or empty
        String value = valueProviderResult.FirstValue;
        if(String.IsNullOrEmpty(value)) return Task.CompletedTask;

        try
        {
            // Deserialize the provided value and set the binding result
            object result = JsonConvert.DeserializeObject(value,bindingContext.ModelTypE);
            bindingContext.Result = ModelBindingResult.success(result);
        }
        catch(JsonException)
        {
            bindingContext.Result = ModelBindingResult.Failed();
        }

        return Task.CompletedTask;
    }
}

然后,您可以在DTO类中使用ModelBinder属性来指示此绑定器应该用于绑定MyJson属性:

public class UploadPayload
{
    public IFormFile File { get; set; }

    [required]
    [StringLength(32)]
    [FromForm]
    public String Md5 { get; set; }

    [ModelBinder(BinderType = typeof(FormDataJsonBinder))]
    public List<String> SessionIds { get; set; }
}

您可以在ASP.NET Core文档中阅读有关自定义模型绑定的更多信息:https://docs.microsoft.com/en-us/aspnet/core/mvc/advanced/custom-model-binding

大佬总结

以上是大佬教程为你收集整理的asp.net-core – ASP.NET Core 1.1中的multipart / form-data(File JSON)帖子的模型绑定全部内容,希望文章能够帮你解决asp.net-core – ASP.NET Core 1.1中的multipart / form-data(File JSON)帖子的模型绑定所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。