ASP.NET MVC 4 JSON привязка к модели представления - ошибка вложенного объекта
У меня возникла проблема с привязкой json к модели представления. Вот мой код:
часть моих ViewModels (AddressViewModel имеет больше свойств):
public class AddressViewModel
{
[Display(Name = "Address_Town", ResourceType = typeof(Resources.PartyDetails))]
public string Town { get; set; }
[Display(Name = "Address_Country", ResourceType = typeof(Resources.PartyDetails))]
public Country Country { get; set; }
}
public class Country : EntityBase<string>
{
public string Name { get; set; }
protected override void Validate()
{
if (string.IsNullOrEmpty(Name))
{
base.AddBrokenRule(new BusinessRule("CountryName", "Required"));
}
}
}
JavaScript:
$(document).on("click", "#addAddress", function () {
var jsonData = {
"Town": $('#txt-Town').val(),
"District": $('#txt-District').val(),
"Street": $('#txt-Street').val(),
"PostCode": $('#txt-PostCode').val(),
"FlatNumber": $('#txt-FlatNumber').val(),
"PremiseName": $('#txt-PremiseName').val(),
"PremiseNumber": $('#txt-Premisenumber').val(),
"Country": {
"Name": $('#txt-Country').val(),
}
};
var addressData = JSON.stringify(jsonData);
$.ajax({
url: '/Customer/SaveAddress',
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: addressData,
success: function (result) {
$("#addIndividualAddressDialog").data("kendoWindow").close();
},
error: function (result) {
alert("Failed");
}
});
});
Заголовок контроллера:
[HttpPost]
public ActionResult SaveAddress(AddressViewModel addressViewModel)
Это то, что я вижу с помощью firebug:
![enter image description here]()
И вот что я вижу в VS:
![enter image description here]()
Как вы видите, свойства Plain привязаны правильно, но мой вложенный объект (Страна) имеет значение NULL. Я читал много разных статей, и я до сих пор не знаю, что я делаю неправильно. Помогите мне, пожалуйста!
Ответы
Ответ 1
Проблема заключается в параметре метода действия:
[HttpPost]
public ActionResult SaveAddress(AddressViewModel addressViewModel)
Как вы используете JSON.stringify()
, вы отправляете строку на свой контроллер, а не на объект! Итак, вам нужно сделать некоторые работы для достижения вашей цели:
1) Измените параметр метода действия:
[HttpPost]
public ActionResult SaveAddress(string addressViewModel)
2) десериализуем эту строку для объекта - это AddressViewModel:
IList<AddressViewModel> modelObj = new
JavaScriptSerializer().Deserialize<IList<AddressViewModel>>(addressViewModel);
Итак, ваш последний метод действий должен выглядеть следующим образом:
[HttpPost]
public ActionResult SaveAddress(string addressViewModel)
{
IList<AddressViewModel> modelObj = new
JavaScriptSerializer().Deserialize<IList<AddressViewModel>>(addressViewModel);
// do what you want with your model object ...
}
Ответ 2
Вы можете сохранить существующий ActionMethod без необходимости сериализации json:
На стороне клиента создайте объект из вашего json:
JSON.parse(jsonData)
и отправить это значение в свойство $.ajax data.
Или, вместо создания json, создайте объект:
var dataObject = new Object();
dataObject.Town = $('#txt-Town').val();
dataObject.District = $('#txt-District').val();
...
И снова отправьте этот объект в свойство $.ajax data.
Ответ 3
На самом деле лучшим вариантом является удаление
var addressData = JSON.stringify(jsonData);
и отправьте сам jsonData. ASP.NET MVC автоматически привяжет его, если это фактический объект, а не просто строка.
Оккамская бритва
Ответ 4
Извините, что ответили на старый thread.here, где вы могли бы работать с JsonResult
вместо ActionResult
это ваша подпись
[HttpPost]
public ActionResult SaveAddress(AddressViewModel addressViewModel)
он должен выглядеть как
[HttpPost]
public JsonResult SaveAddress(AddressViewModel addressViewModel)
{
return Json(status);
}
преимущество было бы, если вы используете JsonResult
вместо ActionResult
, что вам не нужно Deserialize
вот ссылка http://codeforcoffee.org/asp-net-mvc-intro-to-mvc-using-binding-json-objects-to-models/ по этой ссылке вы можете получить эту идею.
Ответ 5
ИЛИ вы можете использовать JsonConvert.DeserializeObject<>();
Ниже приведен код десериализации результата JSON.stringify()
IList<AddressViewModel> modelObj = JsonConvert.DeserializeObject<IList<AddressViewModel>>(addressViewModel);
вместо
JavaScriptSerializer().Deserialize<IList<AddressViewModel>>(addressViewModel);
Ответ 6
You must reference to Country object inside jsonData variable. The JSON POST binding will work correctly.
Old code:
var jsonData = {
"Town": $('#txt-Town').val(),
"District": $('#txt-District').val(),
"Street": $('#txt-Street').val(),
"PostCode": $('#txt-PostCode').val(),
"FlatNumber": $('#txt-FlatNumber').val(),
"PremiseName": $('#txt-PremiseName').val(),
"PremiseNumber": $('#txt-Premisenumber').val(),
"Country": {
"Name": $('#txt-Country').val(),
}
New code:
var jsonData = {
"Town": $('#txt-Town').val(),
"District": $('#txt-District').val(),
"Street": $('#txt-Street').val(),
"PostCode": $('#txt-PostCode').val(),
"FlatNumber": $('#txt-FlatNumber').val(),
"PremiseName": $('#txt-PremiseName').val(),
"PremiseNumber": $('#txt-Premisenumber').val(),
"Country.Name": $('#txt-Country').val(),
}