2016-08-17 9 views
2

Я попытался использовать вызов AJAX в проекте MVC5 как и многие аналогичные примеры в Интернете, но каждый раз, когда появляется ошибка, т.е. antiforgerytoken, 500 и т. Д. Я рассматриваю правильный метод вызова AJAX с методом Action Control, который обладает всеми необходимыми свойствами и передает данные модели из View в Controller Action. Вот методы, которые я использовал:Использование вызова AJAX в MVC5

Вид:

@using (Html.BeginForm("Insert", "Account", FormMethod.Post, new { id = "frmRegister" })) 
{ 
    @Html.AntiForgeryToken() 
    //code omitted for brevity 
} 



<script> 

    AddAntiForgeryToken = function (data) { 
    data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val(); 
    return data; 
    }; 

$('form').submit(function (event) { 
     event.preventDefault(); 

     //var formdata = JSON.stringify(@Model); //NOT WORKING??? 
     var formdata = new FormData($('#frmRegister').get(0)); 
     //var token = $('[name=__RequestVerificationToken]').val(); //I also tried to use this instead of "AddAntiForgeryToken" method but I encounter another error 

     $.ajax({ 
      type: "POST", 
      url: "/Account/Insert", 
      data: AddAntiForgeryToken({ model: formdata }), 
      //data: { data: formdata, __RequestVerificationToken: token }, 
      //contentType: "application/json", 
      processData: false, 
      contentType: false, 

      datatype: "json", 
      success: function (data) { 
       $('#result').html(data); 
      } 
     }); 

    }); 
</script> 

Контроллер: Код не может попасть к этому методу действий в связи с antiforgerytoken или аналогичная проблема.

[HttpPost] 
[AllowAnonymous] 
[ValidateAntiForgeryToken] 
public JsonResult Insert(RegisterViewModel model) 
{ 
    try 
    { 
     //... 
     //code omitted for brevity 
    } 
} 

Мне просто нужны правильные методы AJAX и Action, которые могут использоваться для операций CRUD в MVC5. Любая помощь будет оценена по достоинству.

UPDATE: Вот некоторые моменты, о которых мне нужно уточнить:

1) Мы не использовали «__RequestVerificationToken», и я не уверен, что если мы посылаем его к надлежащему контроллеру (это, кажется, быть как cookie в заголовках запроса Firebug, но я не уверен, что все в порядке или нет). Есть идеи?

2) Должен ли я использовать var formdata = new FormData ($ ('# frmRegister'). Get (0)); когда я загружаю файлы?

3) Почему я должен избегать использования processData и contentType в этом сценарии?

4) Является ли метод контроллера и ошибка в методе AJAX в порядке? Или там отсутствует какая-либо дополнительная часть?

+0

Использование 'var formdata = new FormData ($ ('# frmRegister'). Get (0));' будет включать токен antiforgery. Все, что вам нужно, это «data: formdata», хотя неясно, почему вы используете 'FormData' (вы также загружаете файлы?) –

ответ

3

Если модель на ваш взгляд, является RegisterViewModel и вы сгенерировали элементы формы правильно с помощью сильно типизированных HtmlHelper методы, а затем с помощью либо new FormData($('#frmRegister').get(0)) или $('#frmRegister').serialize() правильно отправит значения всех элементов управления формы в тегах <form>, включая токен, и нет необходимости снова добавлять токен.

Если ваша форма не включает в себя входной файл, то код должен быть

$('form').submit(function (event) { 
    event.preventDefault(); 
    var formData = $('#frmRegister').serialize(); 
    $.ajax({ 
     type: "POST", 
     url: '@Url.Action("Insert", "Account")', // do not hard code your url's 
     data: formData, 
     datatype: "json", // refer notes below 
     success: function (data) { 
      $('#result').html(data); 
     } 
    }); 
}); 

или более просто

$.post('@Url.Action("Insert", "Account")', $('#frmRegister').serialize(), function(data) { 
    $('#result').html(data); 
}); 

Если вы загружаете файлы, то вам нужно вам нужно использовать FormData и код должен быть (см также this answer и

$('form').submit(function (event) { 
    event.preventDefault(); 
    var formData = new FormData($('#frmRegister').get(0)); 
    $.ajax({ 
     type: "POST", 
     url: '@Url.Action("Insert", "Account")', 
     data: formData, 
     processData: false, 
     contentType: false, 
     datatype: "json", // refer notes below 
     success: function (data) { 
      $('#result').html(data); 
     } 
    }); 
}); 

Обратите внимание, что вы должны установить processData и contentType в false при использовании jQuery с FormData.

Если вы получаете 500(Internal Server Error), это почти всегда означает, что ваш метод контроллера бросает исключение.В вашем случае я подозреваю, что это связано с тем, что ваш метод возвращает частичное представление (как это предлагает строка кода $('#result').html(data); в вашем обратном вызове success), но вы указали, что тип возврата должен быть json (использование вами опции datatype: "json",). Обратите внимание, что не нужно указать опцию dataType (метод .ajax() будет работать его, если он не определен)

Если это не является причиной 500(Internal Server Error), то вам необходимо выполнить отладку кода, чтобы определить, что является причиной искупление. Вы можете использовать инструменты разработчика браузера, чтобы помочь этому процессу. Откройте вкладку «Сеть», запустите функцию (имя функции будет выделено), щелкните по ней, а затем просмотрите ответ. Он будет содержать подробную информацию об истечении срока действия.

+0

Благодарим вас за замечательные объяснения. Я думаю, что эту тему следует разделить на две части, как вы «с и без загрузки файлов», и теперь я полностью разъясняюсь с помощью ваших ответов. С другой стороны, я уверен, что эти ответы помогут многим людям, которым надоело искать правильное решение в отношении вызова AJAX :) С уважением ... –

+0

Поскольку я перегрузил проблемы, связанные с использованием AJAX в MVC, я продолжу с призывом AJAX ко всем действиям в моем проекте MVC. Вы рекомендуете это делать, или есть какой-то момент, на который я должен обратить внимание? –

+0

Единственная причина использования ajax - остаться на одной странице. Во многих случаях вы, вероятно, захотите просто сделать обычную передачу и перенаправить на другое представление в методе POST (или вернуть представление, если 'ModelState' недействительно). В вашем случае вам кажется, что вы хотите что-то сохранить, а затем обновите текущую страницу с некоторыми дополнительными данными, и в этом случае использование ajax является подходящим. Его распространенная ошибка для новичков, использующих ajax, а затем в обратном вызове успеха сделайте 'location.href = '....' 'для перенаправления (что бессмысленно) –

1

CONTENTTYPE должен быть application/x-www-form-urlencoded

Попробуйте этот код

<script> 
$('form').submit(function (event) { 
     event.preventDefault(); 

    $.ajax({ 
     method: "POST", 
     url: "/Account/Insert", 
     data: $(this).serialize(), 
     contentType:"application/x-www-form-urlencoded", 
     success: function (data) { 
     $('#result').html(data); 
     }, 
     error: function (jqXHR, textStatus, errorThrown) { 
      console.log(errorThrown); 
     } 
    }); 
}); 
    </script> 
+0

« TypeError: Аргумент 1 из FormData.constructor не реализует интерфейс HTMLFormElement ». >>> var formData = new FormData ($ ('# frmRegister')); –

+0

Я изменил код, попробуйте это и сообщите мне, что произойдет. –

+1

Неправильно. 'contentType' должен быть установлен в' false' для того, чтобы 'FormData' работал (как это сделал OP) –

Смежные вопросы