Ajax-запрос передается как GET-запрос вместо PUT-запроса. - PullRequest
0 голосов
/ 12 января 2019

Я создал форму, через которую пользователь вводит данные, и после нажатия кнопки отправки данные передаются как запрос PUT Ajax. Проблема в том, что он фактически не передается как запрос PUT, вместо этого при исследовании выясняется, что он фактически передается как запрос GET, а данные являются строкой запроса, а не отправляются в параметрах тела для запроса PUT. .

Я попытался отладить код jquery через firefox, но после отправки отладчик не делает паузу для перехода по странице, вместо этого он отправляет запрос GET со строкой запроса, передаваемой в качестве данных, предоставленных в переменной vm в запросе ajax , Вот моя форма HTML.cs:

@model Auth.ViewModels.NewCustomerViewModel
@{
    ViewBag.Title = "New";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>New Customer</h2>


<form id="idk">
    @Html.ValidationSummary(true, "Please fix the following errors: ")
    <div class="form-group">
        @Html.LabelFor(m => m.Customer.Name)
        @Html.TextBoxFor(m => m.Customer.Name, new { @class = "form-control", @id = "customername" })
        @Html.ValidationMessageFor(m => m.Customer.Name)
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.Customer.MembershipTypeId)
        @Html.DropDownListFor(m => m.Customer.MembershipTypeId, new SelectList(Model.MembershipTypes, "Id", "MembershipName"), "Select Membership Type", new { @class = "form-control", @id = "membershipname" })
        @Html.ValidationMessageFor(m => m.Customer.MembershipTypeId)
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.Customer.BirthDate)
        @Html.TextBoxFor(m => m.Customer.BirthDate, "{0:d MMM yyyy}", new { @class = "form-control", @id = "birthdate" })
        @Html.ValidationMessageFor(m => m.Customer.BirthDate)
    </div>

    <div class="checkbox">
        <label>
            @Html.CheckBoxFor(m => m.Customer.IsSubscribedToNewsletter, new { @id = "subscribename" }) Subscribe to Newsletter?
        </label>
    </div>

    <div class="checkbox">
        <label>
            @Html.CheckBoxFor(m => m.Customer.Irresponsible, new { @id = "irresponsiblename" }) Delinquent Person
        </label>
    </div>
    @Html.HiddenFor(m => m.Customer.Id, new { @id = "id" })
    @Html.AntiForgeryToken()
    <button type="submit" id="submit" class="btn btn-primary">Save</button>

</form>


@section scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script>
        $(document).ready(function () {
            $("#submit").on("click",function (event) {
                var vm = { id: $("#id").val(), Name: $("#customername").val(), IsSubscribedToNewsLetter: $("#subscribename").val(), MembershipTypeId: $("#membershipname").val(), BirthDate: $("#birthdate").val(), Irresponsible: $("#irresponsiblename").val(), Id: $("#id").val()  };


   $.ajax({
                url: "/api/Customers/UpdateCustomer",
                method: "PUT",
                data: {vm },
            success: function () {
                Location("customers/Index");
                //button.parents("tr").remove();
            }
        });
        });

        });



    </script>

}

Вот серверная часть, которая обрабатывает этот запрос PUT:

 [HttpPut]
        public IHttpActionResult UpdateCustomer(int id, CustomerDto customerDto)
        {
            if (!ModelState.IsValid)
                return BadRequest();
            var customerInDb = _context.Customer.SingleOrDefault(c => c.Id == id);
            if (customerInDb == null)
                return NotFound();
            Mapper.Map<CustomerDto, Customer>(customerDto, customerInDb);
            _context.SaveChanges();
            return Ok();

        }

Я просто не знаю, почему он не передается как запрос PUT на сервер и почему данные передаются как параметр строки запроса. Я ожидал, что он передаст данные с запросом PUT и обновит различные поля в базе данных

Ответы [ 3 ]

0 голосов
/ 12 января 2019

Вы, как правило, похожи на отправку данных в неправильном формате, который неожиданно интерпретируется как другой метод с другими параметрами (которых никогда не существует) или приводит к ошибке при привязке данных к нужным типам данных. Например, вы отправляете следующие данные:

var vm = {
    id: 123
};

Ожидаемая конечная точка API

GET /account/update-customer/123 // OK 200

Фактический URL отправлен

// Url encoded. This method expects an integer as parameter but string was passed.
GET /account/update-customer/vm%5Bid%5D=123 // Internal Server Error 500

Так что, если вы отправляете их как данные формы , удалите фигурные скобки из объекта vm (поскольку он уже является объектом в любом случае), чтобы HTTP правильно выпекал их в URL, или просто дайте jQuery serialize данные для вас и без проблем (вы, вероятно, должны это сделать) .

Вот полные фрагменты в действии, а также мои маленькие рекомендации по рефакторингу:

Вы, вероятно, уже делаете это, но используете Html.BeginForm, который позволяет получить URL-адрес API более удобным способом на более позднем этапе (например, в вызовах AJAX).

Переключение с

<form id="idk">
  <div class="form-group">
    @Html.LabelFor(m => m.Customer.Name)
    @Html.TextBoxFor(m => m.Customer.Name, new { @class = "form-control", @id = "customername" })
    @Html.ValidationMessageFor(m => m.Customer.Name)
  </div>

  [...]

К

@using (Html.BeginForm("UpdateCustomer", "Account"))
{
  <div class="form-group">
    @Html.LabelFor(m => m.Customer.Name)
    @Html.TextBoxFor(m => m.Customer.Name, new { @class = "form-control" })
    @Html.ValidationMessageFor(m => m.Customer.Name)
  </div>

  [...]

  <!-- No need for manually specifing the id here since it will be taken care of by the framework -->
  @Html.HiddenFor(m => m.Customer.Id)
}

Файл Javascript

$("form#idk").submit(function (e) {
   e.preventDefault();

   //var vm = {
   //   id: $("#id").val(),
   //   Name: $("#customername").val(),
   //   IsSubscribedToNewsLetter: $("#subscribename").val(),
   //   MembershipTypeId: $("#membershipname").val(),
   //   BirthDate: $("#birthdate").val(),
   //   Irresponsible: $("#irresponsiblename").val(),
   //   Id: $("#id").val()
   //};

   // This one-liner should do the magic for you
   var vm = $(this).serialize();

  $.ajax({
    // Made available by the above Html.BeginForm().
    // This way, when you decide to change the URL later, you won't have to deal
    // with having to possibly update this in multiple places
    url: this.action,

    method: "PUT",
    data: vm,
    success: function (data) {
      // ...
    }
  });
});

enter image description here Надеюсь, это поможет.

0 голосов
/ 13 января 2019

Используйте кнопку типа кнопки вместо отправки, форма отправки по умолчанию принимает метод GET

0 голосов
/ 12 января 2019

Я предполагаю, что ваша версия jQuery <1.9. Если это так, вам нужно использовать <code>type вместо method, см. Здесь :

type (по умолчанию: 'GET') Тип: String Псевдоним для метода. Вы должны использовать введите, если вы используете версии JQuery до 1.9.0.


 $.ajax({
     url: "/api/Customers/UpdateCustomer",
     type: "PUT",
     data: { vm },
     success: function () {
            Location("customers/Index");
            //button.parents("tr").remove();
        }
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...