C# AspNetCore3包含文件和字典的多部分post未按预期工作
在我的AspNetCore3控制器中有一个post方法,它接受一个文件和一个包含元数据的字典。我遇到的问题是字典不是自动反序列化的,我必须手动反序列化C# AspNetCore3包含文件和字典的多部分post未按预期工作,c#,asp.net-core,asp.net-core-webapi,C#,Asp.net Core,Asp.net Core Webapi,在我的AspNetCore3控制器中有一个post方法,它接受一个文件和一个包含元数据的字典。我遇到的问题是字典不是自动反序列化的,我必须手动反序列化 /// <summary>Upload an attachment</summary> [HttpPost("{id}")] [DisableRequestSizeLimit] public async Task<ActionResult> Upl
/// <summary>Upload an attachment</summary>
[HttpPost("{id}")]
[DisableRequestSizeLimit]
public async Task<ActionResult> UploadAttachment(
[FromRoute] string id,
IFormFile file,
[FromForm] Dictionary<string, string> metadata)
{
// TODO figure out why the metadata isn't loaded/deserialized from the form data
Dictionary<string, string> dict = null;
if (Request.Form.TryGetValue(nameof(metadata), out var values))
{
try
{
dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(values);
}
catch { /* ignore */ }
}
await m_service.UploadAttachment(id, file, dict);
return Ok();
}
///上传附件
[HttpPost(“{id}”)]
[DisableRequestSizeLimit]
公共异步任务上载附件(
[FromRoute]字符串id,
格式化文件,
[FromForm]字典元数据)
{
//TODO找出元数据没有从表单数据加载/反序列化的原因
字典dict=null;
if(Request.Form.TryGetValue(nameof(元数据),out var值))
{
尝试
{
dict=JsonConvert.DeserializeObject(值);
}
捕获{/*忽略*/}
}
等待m_服务。上传附件(id、文件、dict);
返回Ok();
}
有人知道为什么默认反序列化不起作用吗?这取决于您如何发出post请求。如果您使用的是Postman,那么根据UploadAttachment()操作签名,它应该是这样的 以下是原始或请求:
POST / HTTP/1.1
Host: localhost:62117
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Host: localhost:62117
Content-Length: 294
Content-Disposition: form-data; name="metadata[key1]"
value1
------WebKitFormBoundary7MA4YWxkTrZu0gW--,
Content-Disposition: form-data; name="metadata[key1]"
value1
------WebKitFormBoundary7MA4YWxkTrZu0gW--
Content-Disposition: form-data; name="metadata[key2]"
value2
------WebKitFormBoundary7MA4YWxkTrZu0gW--
如果您想像这样传递json内容
然后需要添加自定义模型绑定器
public class DictionaryBinder : IModelBinder
{
public async Task BindModelAsync(ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
if (bindingContext.HttpContext.Request.HasFormContentType)
{
var form = bindingContext.HttpContext.Request.Form;
var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(form[bindingContext.FieldName].ToString());
bindingContext.Result = ModelBindingResult.Success(data);
}
}
}
公共类字典binder:IModelBinder
{
公共异步任务BindModelAsync(ModelBindingContext bindingContext)
{
if(bindingContext==null)
{
抛出新ArgumentNullException(nameof(bindingContext));
}
if(bindingContext.HttpContext.Request.HasFormContentType)
{
var form=bindingContext.HttpContext.Request.form;
var data=JsonConvert.DeserializeObject(形式为[bindingContext.FieldName].ToString());
bindingContext.Result=ModelBindingResult.Success(数据);
}
}
}
然后
公共异步任务上传附件(
[FromRoute]字符串id,
格式化文件,
[FromForm][ModelBinder(typeof(DictionaryBinder))]字典元数据)
对于邮递员来说,这确实有效,但斯威格构建了这篇文章,但这不起作用:curl-X post”http://localhost:5000/api/Items/123“-H”接受:*/*“-H”授权:承载xxxx“-H”内容类型:多部分/表单数据“-F”元数据={“additionalProp1”:“字符串”,“additionalProp2”:“字符串”,“additionalProp3”:“字符串”}”-F“file=@pasfoto.jpg;type=image/jpeg“
因为要将json传递给元数据,所以需要像上面这样的自定义模型绑定器
public async Task<ActionResult> UploadAttachment(
[FromRoute] string id,
IFormFile file,
[FromForm][ModelBinder(typeof(DictionaryBinder))] Dictionary<string, string> metadata)