C# 在同一操作中发送多部分和json

C# 在同一操作中发送多部分和json,c#,asp.net-mvc,asp.net-core,C#,Asp.net Mvc,Asp.net Core,我有用于编辑人员表的控制器和操作 我正在用信息填写表单,若用户更改了任何内容,我将启用“保存”按钮来调用操作 人物包含信息和个人资料图片 问题是,仅当我浏览配置文件图片并将表单作为多部分/表单数据发送时,才会调用操作。但是,如果我调用它而不发送文件,只需从I获取错误500 [Route("EditPerson")] [HttpPost] public IActionResult EditPerson(PersonDto Person) { //Do something with perso

我有用于编辑人员表的控制器和操作

我正在用信息填写表单,若用户更改了任何内容,我将启用“保存”按钮来调用操作

人物包含信息和个人资料图片

问题是,仅当我浏览配置文件图片并将表单作为多部分/表单数据发送时,才会调用操作。但是,如果我调用它而不发送文件,只需从I获取错误500

[Route("EditPerson")]
[HttpPost]
public IActionResult EditPerson(PersonDto Person) {
   //Do something with person model
   return Ok();
}
如果我想将其作为application/json发送并绑定到一个模型,我必须在PersonModel参数中使用[FromBody]注释

现在,我发送多部分/表单数据——只有上传新图片时才会绑定,如果只更改输入字段时才会绑定——我得到错误500

[Route("EditPerson")]
[HttpPost]
public IActionResult EditPerson(PersonDto Person) {
   //Do something with person model
   return Ok();
}
我正在使用jQuery表单插件:

 $('#personEditForm').ajaxSubmit({
      url: 'PersonSettings/EditPerson',
     type: 'post',
     contentType: 'multipart/form-data',
     success: successEditPerson,
     resetForm: true,
     beforeSubmit: beforeEditPerson
});
表格:


一般的

人名: * 人员姓名: *
您可以检查请求是否包含多部分内容,因此相应地,您可以处理相同的内容。如果包含多部分数据,则在此处执行逻辑

   [HttpPost]
    public IActionResult Index([FromBody] personalInfo)
    {
        //check for multipart request
        if (MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
         {                  
              // request for uploaded files 
              var file = Request.Form.Files[0];
         }

     }

您不能将
multipart/form data
application/json
编码请求发送到同一个操作。modelbinder需要提前知道如何处理请求正文,需要指定
[FromForm]
(默认)或
[FromBody]
。如果您需要同时处理这两个操作,那么您需要两个单独的操作,尽管您可以考虑实际逻辑以保持干燥。例如:

private IActionResult EditPersonCore(PersonDto person)
{
   //Do something with person model
   return Ok();
}

[HttpPost("EditPersonForm"]
public IActionResult EditPersonForm(PersonDto person) => EditPersonCore(person);

[HttpPost("EditPersonJson"]
public IActionResult EditPersonJson([FromBody]PersonDto person) => EditPersonCore(person);
显然,这意味着你将有两条不同的路线,但这是你能做的最好的

也就是说,您不需要仅仅因为有一个文件就发布为
multipart/formdata
。您可以通过JSON发布文件;它只需要作为Base64编码的字节数组发送。在JavaScript中,您可以通过以下方式实现:

var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
    // here `reader.result` will hold your file as base64
};

在服务器端,您只需绑定到类型为
byte[]
的属性。ASP.NET Core中的modelbinder将透明地将Base64编码字符串反序列化为
字节[]

不显式设置
contentType:“多部分/表单数据”
。它还需要设置一个“边界”值,由浏览器处理。只要删除这条线,再试一次,我认为它应该会有所帮助。你能给我们看一下你的表格的HTML吗。顺便说一句,我不明白你为什么认为任何JSON都被发布了。它应该只提交一个由文件数据组成的多部分请求,然后以通常的url编码格式提交其他参数。。我将用表格编辑我的答案可能重复的“没有工作”的意思到底是什么?与您描述的行为相同,还是有所不同?顺便问一下,500的误差是多少?您应该能够调试服务器或查看日志,以了解底层问题是什么。这可能会有帮助。