Отправить multipart и json в одном действии - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть Контроллер и Действие для редактирования Персона Таблица.

Я заполняю форму информацией, и если пользователь что-то меняет, я включаю кнопку Сохранить, чтобы вызвать действие.

Персона содержит информацию и изображение профиля.

Проблема в том, Действие вызывается только тогда, когда я просматриваю изображение профиля и отправляю форму как multipart / form-data. Но если я звоню без отправки файла, просто получаю ошибку 500.

Если я хочу отправить его как application / json и связать его с моделью, я должен использовать аннотацию [FromBody] в Действие для параметра PersonModel.

Теперь я отправляю 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 для добавления Id для Person.

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Вы не можете отправлять оба закодированных запроса multipart/form-data и application/json одному и тому же действию. Привязка модели должна знать заранее, как обрабатывать тело запроса, требуя указать либо [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/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[].

0 голосов
/ 05 сентября 2018

Вы можете проверить запрос на содержание 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];
         }

     }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...