Правильный способ использования AJAX Post в jquery для передачи модели из строго типизированного представления MVC3
Я начинающий программист, поэтому, пожалуйста, простите меня, если некоторые из моих "жаргонов" неверны.
У меня есть проект с использованием ASP.NET с использованием среды MVC3.
Я работаю над административным представлением, в котором администратор изменит список оборудования. Одной из функций является кнопка "Обновить", которую я хочу использовать jquery для динамического редактирования записи на веб-странице после отправки сообщения контроллеру MVC.
Я предполагаю, что этот подход "безопасен" в одном административном настройке, где минимальная проблема с веб-страницей, выходящей из синхронизации с базой данных.
Я создал представление, которое строго типизировано, и надеялось передать данные модели в элемент управления MVC, используя пост AJAX.
В следующем посте я нашел то, что похоже на то, что я ищу:
JQuery Ajax и ASP.NET MVC3, вызывающие нулевые параметры
Я буду использовать образец кода из вышеприведенного сообщения.
Модель:
public class AddressInfo
{
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
}
Контроллер:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Check(AddressInfo addressInfo)
{
return Json(new { success = true });
}
}
script в представлении:
<script type="text/javascript">
var ai = {
Address1: "423 Judy Road",
Address2: "1001",
City: "New York",
State: "NY",
ZipCode: "10301",
Country: "USA"
};
$.ajax({
url: '/home/check',
type: 'POST',
data: JSON.stringify(ai),
contentType: 'application/json; charset=utf-8',
success: function (data.success) {
alert(data);
},
error: function () {
alert("error");
}
});
</script>
У меня еще не было возможности использовать приведенное выше. Но мне было интересно, если бы это был "лучший" способ передать данные модели обратно в элемент управления MVC с помощью AJAX?
Должен ли я беспокоиться о том, чтобы разоблачить информацию о модели?
Ответы
Ответ 1
Вы можете пропустить объявление var и stringify. В противном случае это будет работать нормально.
$.ajax({
url: '/home/check',
type: 'POST',
data: {
Address1: "423 Judy Road",
Address2: "1001",
City: "New York",
State: "NY",
ZipCode: "10301",
Country: "USA"
},
contentType: 'application/json; charset=utf-8',
success: function (data) {
alert(data.success);
},
error: function () {
alert("error");
}
});
Ответ 2
Я нашел 3 способа реализовать это:
Класс С#:
public class AddressInfo {
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
}
Действие:
[HttpPost]
public ActionResult Check(AddressInfo addressInfo)
{
return Json(new { success = true });
}
JavaScript вы можете сделать это тремя способами:
1) Строка запроса:
$.ajax({
url: '/en/Home/Check',
data: $('#form').serialize(),
type: 'POST',
});
Данные здесь представляют собой строку.
"Address1=blah&Address2=blah&City=blah&State=blah&ZipCode=blah&Country=blah"
2) Массив объекта:
$.ajax({
url: '/en/Home/Check',
data: $('#form').serializeArray(),
type: 'POST',
});
Данные здесь представляют собой массив пар ключ/значение:
=[{name: 'Address1', value: 'blah'}, {name: 'Address2', value: 'blah'}, {name: 'City', value: 'blah'}, {name: 'State', value: 'blah'}, {name: 'ZipCode', value: 'blah'}, {name: 'Country', value: 'blah'}]
3) JSON:
$.ajax({
url: '/en/Home/Check',
data: JSON.stringify({ addressInfo:{//missing brackets
Address1: $('#address1').val(),
Address2: $('#address2').val(),
City: $('#City').val(),
State: $('#State').val(),
ZipCode: $('#ZipCode').val()}}),
type: 'POST',
contentType: 'application/json; charset=utf-8'
});
Данные представляют собой сериализованную строку JSON. Обратите внимание, что имя должно совпадать с именем параметра на сервере!
='{"addressInfo":{"Address1":"blah","Address2":"blah","City":"blah","State":"blah", "ZipCode", "blah", "Country", "blah"}}'
Ответ 3
Так оно и работало для меня:
$.post("/Controller/Action", $("#form").serialize(), function(json) {
// handle response
}, "json");
[HttpPost]
public ActionResult TV(MyModel id)
{
return Json(new { success = true });
}
Ответ 4
то, что у вас есть, хорошо - однако, чтобы сохранить некоторую типизацию, вы можете просто использовать для своих данных
data: $('#formId').serialize()
см. http://www.ryancoughlin.com/2009/05/04/how-to-use-jquery-to-serialize-ajax-forms/ для подробностей, синтаксис довольно прост.
Ответ 5
Если использовать MVC 5, прочитайте это решение!
Я знаю вопрос, специально названный для MVC 3, но я наткнулся на эту страницу с MVC 5 и хотел опубликовать решение для кого-либо еще в моей ситуации. Я пробовал вышеупомянутые решения, но они не работали для меня, фильтр действий не был достигнут, и я не мог понять, почему. Я использую версию 5 в своем проекте и в итоге получил следующий фильтр действий:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Filters;
namespace SydHeller.Filters
{
public class ValidateJSONAntiForgeryHeader : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
string clientToken = filterContext.RequestContext.HttpContext.Request.Headers.Get(KEY_NAME);
if (clientToken == null)
{
throw new HttpAntiForgeryException(string.Format("Header does not contain {0}", KEY_NAME));
}
string serverToken = filterContext.HttpContext.Request.Cookies.Get(KEY_NAME).Value;
if (serverToken == null)
{
throw new HttpAntiForgeryException(string.Format("Cookies does not contain {0}", KEY_NAME));
}
System.Web.Helpers.AntiForgery.Validate(serverToken, clientToken);
}
private const string KEY_NAME = "__RequestVerificationToken";
}
}
- Обратите внимание на библиотеки using System.Web.Mvc
и using System.Web.Mvc.Filters
, а не на http
(я думаю, что это одна из вещей, которые были изменены с MVC v5.
Затем просто примените фильтр [ValidateJSONAntiForgeryHeader]
к вашему действию (или контроллеру), и он должен быть вызван правильно.
В моей странице макета прямо над </body>
У меня есть @AntiForgery.GetHtml();
Наконец, на моей странице Razor я делаю вызов ajax следующим образом:
var formForgeryToken = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
type: "POST",
url: serviceURL,
contentType: "application/json; charset=utf-8",
dataType: "json",
data: requestData,
headers: {
"__RequestVerificationToken": formForgeryToken
},
success: crimeDataSuccessFunc,
error: crimeDataErrorFunc
});