我有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。
您不能将multipart/form-data
和application/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[]
。
您可以检查请求是否包含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];
}
}