dotnet core 从表单数据中获取字典
dotnet core get dictionairy from form data
如何从 form-data
获得 Dictionairy<string, string>
?
查看模型:
public class SubmitRequestModel
{
public Dictionairy<string, string> InputFields { get; set; }
public List<IFormFile> Attachments { get; set; }
}
操作:
[HttpPut("{id:int}")]
public async Task<IActionResult> Submit(int id, [FromForm] SubmitRequestModel model)
{
// model.InputFields is initialized but it's count is 0
// do whatever
}
这是一个 API 控制器。与 cshtml 或剃刀无关。
所以 model.InputFields
不是 null
,但它的计数是 0
。当我查看原始请求时。我可以看到输入已收到,但未绑定到模型中的字典。
Request.Form
集合的值:https://prnt.sc/11x532p
我需要使用表单数据,因为我们正在根据请求上传文件。这需要 multipart/form-data
.
如何将数据成功解析为模型?
关于我如何测试的信息:
我有 swagger 设置。我将生成的 Swagger OpenAPI json 导入到 Postman 中并以这种方式进行测试。我相信这应该是 Swagger 生成的正确请求。但我不确定它是否以正确的方式格式化字典。这将是 JSON 数据请求的正确方法。但我不确定这是否适用于此。
我觉得你的问题和给定的link是一样的,直接过一遍link可能对你有帮助。
或
所以一种解决方案(这不是我最喜欢的但它有效)是手动解析字典。
行动的第一件事:
if (model.InputFields == null || model.InputFields.Count == 0)
{
var rawInputFields = Request.Form["InputFields"].ToString();
model.InputFields = JsonSerializer.Deserialize<Dictionary<string, string>>(rawInputFields);
}
您可以通过自定义实现此目的 IModelBinder
:
public class DictionaryBinder<TKey, TValue> : IModelBinder
{
public 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 = JsonSerializer.Deserialize<Dictionary<TKey, TValue>>(form[bindingContext.FieldName]);
bindingContext.Result = ModelBindingResult.Success(data);
}
return Task.CompletedTask;
}
}
模型class将变为:
public class SubmitRequestModel
{
[FromForm]
[ModelBinder(BinderType = typeof(DictionaryBinder<string, string>))]
public Dictionary<string, string> InputFields { get; set; }
public List<IFormFile> Attachments { get; set; }
}
如何从 form-data
获得 Dictionairy<string, string>
?
查看模型:
public class SubmitRequestModel
{
public Dictionairy<string, string> InputFields { get; set; }
public List<IFormFile> Attachments { get; set; }
}
操作:
[HttpPut("{id:int}")]
public async Task<IActionResult> Submit(int id, [FromForm] SubmitRequestModel model)
{
// model.InputFields is initialized but it's count is 0
// do whatever
}
这是一个 API 控制器。与 cshtml 或剃刀无关。
所以 model.InputFields
不是 null
,但它的计数是 0
。当我查看原始请求时。我可以看到输入已收到,但未绑定到模型中的字典。
Request.Form
集合的值:https://prnt.sc/11x532p
我需要使用表单数据,因为我们正在根据请求上传文件。这需要 multipart/form-data
.
如何将数据成功解析为模型?
关于我如何测试的信息:
我有 swagger 设置。我将生成的 Swagger OpenAPI json 导入到 Postman 中并以这种方式进行测试。我相信这应该是 Swagger 生成的正确请求。但我不确定它是否以正确的方式格式化字典。这将是 JSON 数据请求的正确方法。但我不确定这是否适用于此。
我觉得你的问题和给定的link是一样的,直接过一遍link可能对你有帮助。
或
所以一种解决方案(这不是我最喜欢的但它有效)是手动解析字典。
行动的第一件事:
if (model.InputFields == null || model.InputFields.Count == 0)
{
var rawInputFields = Request.Form["InputFields"].ToString();
model.InputFields = JsonSerializer.Deserialize<Dictionary<string, string>>(rawInputFields);
}
您可以通过自定义实现此目的 IModelBinder
:
public class DictionaryBinder<TKey, TValue> : IModelBinder
{
public 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 = JsonSerializer.Deserialize<Dictionary<TKey, TValue>>(form[bindingContext.FieldName]);
bindingContext.Result = ModelBindingResult.Success(data);
}
return Task.CompletedTask;
}
}
模型class将变为:
public class SubmitRequestModel
{
[FromForm]
[ModelBinder(BinderType = typeof(DictionaryBinder<string, string>))]
public Dictionary<string, string> InputFields { get; set; }
public List<IFormFile> Attachments { get; set; }
}