2013-07-25 3 views
17

Я изучал примеры того, как это сделать на SO, и насколько я могу судить, я пробовал все примеры, которые я могу найти без успеха до сих пор. Я попытался изменить некоторые из реализаций моего сценария, но это пока не удалось.AJAX Проводка ValidateAntiForgeryToken без формы для метода действия MVC

Я это на моей странице в _layout.cshtml так у меня всегда есть в наличии: маркер

<form id="__AjaxAntiForgeryForm" action="#" method="post"> @Html.AntiForgeryToken()</form> 

У меня также есть этот метод в моем в JavaScript Utils файл:

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

Это все работая как ожидалось, и я получаю токен анти-подделки. Мой реальный код регистраци:

myPage.saveData = function() { 
    var saveUrl = '/exercises/PostData'; 

    var myData = JSON.stringify(myPage.contextsArrays); 

    $.ajax({ 
     type: 'POST', 
     async: false, 
     url: saveUrl, 
     data: AddAntiForgeryToken({ myResults: myData }), 
     success: function() { 
      alert('saved'); 
     }, 
     dataType: 'json', 
     contentType: "application/json; charset=utf-8" 
    }); 
}; 

Мой метод действий выглядит следующим образом:

[HttpPost, ValidateAntiForgeryToken, JsonExceptionFilter] 
    public JsonResult PostData(List<ResultsDc> myResults) 
    { 
     return Json(_apiClient.SubmitResults(myResults)); 
    } 

Я тестировал это с различными реализациями я пытался, и ответ всегда:

{"errorMessage":"The required anti-forgery form field \"__RequestVerificationToken\" is not present."} 

Я не размещаю форму, это всего лишь массив данных, но, проверяя данные, которые фактически отправляются, Json не выглядит правильно (все кодируется), но имя параметра __RequestVerificationToken является re и значение токена.

В настоящий момент я довольно смущен этим и не могу найти правильный способ отправить токен, чтобы вызвать действие MVC. Если я удалю атрибут ValidateAntiForgeryToken и у вас есть JSON.stringify(myPage.contextsArrays);, в качестве данных json выглядит правильно (unencoded) и он отлично отображает.

Как получить этот токен, размещенный правильно без формы?

+0

Я смущен. Если вы этого не видели, а ваш ответ ниже - кто-то elses (я видел этот код на других ответах на SO), почему вы пытаетесь ответить на что-то, чего не понимаете? – Jammer

+0

Не нужно отделять атрибуты ... – Jammer

ответ

27

Картон-разработчик снова поражает.

Все, что я должен был сделать удалить:

contentType: "application/json; charset=utf-8" 

И, делая это, (который изменяет вид запроса пост делается), чтобы получить содержание JSon фактической собственности данных, чтобы правильно выполнить привязку к T тип модели НЕJSON.stringify() данные.

+0

Life saver ... спасибо! этот комментарий был всем, что мне нужно после двухдневного поиска. Очень важно. –

+0

Превосходно! - последовал много решений, но безуспешно, это, однако, оказалось виновным, огромное спасибо! – Dal

+0

Спасибо! Отработайте часы на этом !!! Читайте статью после статьи и просто ничего не получилось. Пробовал так много разных вещей, но все в значительной степени обеспечивал тот же конечный результат, который должен был включать токен проверки при публикации и не мог заставить это работать, пока я не нашел ваше предложение от fluke !! Все еще не могу в это поверить! Спасибо, что поделились!! – Thierry

1

Проверка жестко запрограммирована на данные формы.

https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.WebPages/Helpers/AntiXsrf/AntiForgeryTokenStore.cs

public AntiForgeryToken GetFormToken(HttpContextBase httpContext) 
    { 
     string value = httpContext.Request.Form[_config.FormFieldName]; 

Вы можете имитировать форму представления, следуя определенный формат. Для этого см. How to mimic an HTML form submission in a POST request?

Если вы хотите, вы также можете сделать свой собственный валидатор. How to POST JSON data to an Asp.Net MVC 2 app with ValidateAntiForgeryToken объясняет, как это сделать. Это для MVC 2, но вы можете получить от него некоторые идеи.

+0

Как только я разместил это, я решил все это. – Jammer

+0

Большая часть этого полного переполнения и совершенно не требуется ... – Jammer

+0

Несомненно, пользовательский валидатор можно рассматривать как излишний. Я просто объясню причину проблемы и два возможных решения. Ответ, который вы опубликовали, в значительной степени является конечным результатом информации в моей первой ссылке. – Stijn

9

(Примечание: Я знаю, что это не все, что сильно отличается от того, что уже здесь)

Я понимаю, что это уже есть ответ, но я сделал это совсем немного и добавить свой ответ куча.У меня нет форм на моем сайте, поэтому мне пришлось придумать способы справиться с этим. Много исследований здесь о stackoverflow и некоторых блогах, наконец, дал мне информацию, в которой я нуждался.

Во-первых, вот мой код в верхней части моей страницы "мастер" (MVC Razor):

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" })) 
{ 
    @Html.AntiForgeryToken() 
} 

Затем во всех Ajax вызовов (JQuery), я начинаю так:

var token = $("#__AjaxAntiForgeryForm input").val(); 
var dataObject = { 
    __RequestVerificationToken: token, 
    myData: "whatever" 
}; 

$.ajax({ 
    url: '@Url.Action("action", "controller")', 
    type: 'POST', 
    dataType: 'json', 
    data: dataObject, 
    error: function (jqXHR, textStatus, errorThrown) { 
    console.log("ERROR!"); 
    }, 
    success: function (data) { 
    //whatever 
    } 
}); 

Наконец, в стороне контроллера вещей, это работает отлично:

public class controllerController : Controller 
{ 
    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public JsonResult action (myModel myData) 
    { 
     return Json(new { Success = "true" }, JsonRequestBehavior.DenyGet); 
    } 
} 

Надеюсь, это поможет другим в том же лодка.

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