在同一个动作中发送multipart和json

问题描述 投票:-1回答:2

我有Controller和Action来编辑Person表。

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

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

问题是,只有当我浏览个人资料图片并将表单作为multipart / form-data发送时才会调用Action。但是如果我在没有发送文件的情况下调用它,只需要表单我得到错误500。

如果我想将它作为application / json发送并将其绑定到模型,我必须在Action中为PersonModel参数使用[FromBody]注释。

现在我发送multipart / form-data - 它只绑定如果我上传新图片,如果我只改变输入字段 - 我得到错误500。

[Route("EditPerson")]
[HttpPost]
public IActionResult EditPerson(PersonDto Person) {
   //Do something with person model
   return Ok();
}

我正在使用jQuery-Form-Plugin:

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

形成:

 <form id="personEditForm" >
                <h6><b>General</b></h6>
                <hr/>
                <fieldset>
                    <div class="row">
                        <div class="col-md-4">
                            <div class="form-group">
                                <label for="Name">
                                    Person Name :
                                    <span class="danger">*</span>
                                </label>
                                <input autocomplete="off" type="text" class="form-control required" id="NameEdit" name="Name">
                            </div>
                        </div>
                        <div class="col-md-4">
                            <div class="form-group">
                                <label for="Surename">
                                    Person Surename :
                                    <span class="danger">*</span>
                                </label>
                                <input autocomplete="off" type="text" class="form-control required" id="SurenameEdit" name="Surename">
                            </div>
                        </div
                        <div class="col-md-4">
                            <div class="form-group">
                                <label for="Age">
                                    Person Age :
                                    <span class="danger">*</span>
                                </label>
                                <input autocomplete="off" type="text" class="form-control required" id="AgeEdit" name="Age">
                            </div>
                        </div
                        <div class="col-md-4">
                            <div class="form-group">
                                <label for="PersonPic">
                                    Profile pic (Must be in size ..x..) :
                                    <span class="danger">*</span>
                                </label>
                                <input type="file" class="form-control" id="PersonPic" name="PersonPic" accept="image/*" onchange="loadImageEdit(event)">
                            </div>
                        </div>
                        <div class="col-md-4 ">
                            <div class="form-group">
                                <label for="Name">
                                    Profile picture preview:
                                </label>
                                <img id="personImagePreviewEdit" alt="Upload image to preview" style="display: block"src="#"/>
                            </div>
                        </div>
                    </div>
                </fieldset></form>

我正在使用beforeEditPerson函数为Person添加Id。

c# asp.net-mvc asp.net-core
2个回答
2
投票

您不能将multipart/form-dataapplication/json编码请求发送到同一操作。模型绑定器需要事先知道如何处理请求体,需要指定[FromForm](默认值)或[FromBody]。如果你需要同时处理两者,那么你需要两个单独的动作,尽管你可以分解实际的逻辑以保持DRY。例如:

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/form-data一样发布,因为你有一个文件。您可以通过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中的模型绑定器将透明地将Base64编码的字符串反序列化为byte[]


-2
投票

您可以检查请求是否包含Multipart内容,因此您可以进行相同的处理。如果包含多部分数据,那么在这里做你的逻辑

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

     }
© www.soinside.com 2019 - 2024. All rights reserved.