Если вы публикуете его через AJAX с типом контента, установленным на JSON, то MVC 3 сможет правильно связать его в действии вашего контроллера.
$.ajax({
url: location.href,
type: "POST",
data: ko.toJSON(viewModel),
datatype: "json",
contentType: "application/json charset=utf-8",
success: function (data) { alert("success"); },
error: function (data) { alert("error"); }
});
Однако, если, как и в вашем примере, вы хотите сделать обычную запись в форме, включающую JSON, вам нужно проделать еще некоторую работу, поскольку MVC3 не будет автоматически привязывать ее к вашей модели, так кактип содержимого будет application / x-www-form-urlencoded.
У Стива Сандерсона есть более старый пример, который демонстрирует правильную привязку отправленных данных JSON в действии вашего контроллера: http://blog.stevensanderson.com/2010/07/12/editing-a-variable-length-list-knockout-style/
Суть в том, что он создает атрибут с именем FromJson"это выглядит так:
public class FromJsonAttribute : CustomModelBinderAttribute
{
private readonly static JavaScriptSerializer serializer = new JavaScriptSerializer();
public override IModelBinder GetBinder()
{
return new JsonModelBinder();
}
private class JsonModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var stringified = controllerContext.HttpContext.Request[bindingContext.ModelName];
if (string.IsNullOrEmpty(stringified))
return null;
return serializer.Deserialize(stringified, bindingContext.ModelType);
}
}
}
Затем действие выглядит следующим образом:
[HttpPost]
public ActionResult Index([FromJson] IEnumerable<GiftModel> gifts)
Кроме того, если вам не нравится использовать атрибут, вы можете зарегистрироватьтипа, чтобы всегда использовать определенную модель связующего.
Вы можете создать подшивку модели, которая выглядит следующим образом:
public class JsonModelBinder: IModelBinder
{
private readonly static JavaScriptSerializer serializer = new JavaScriptSerializer();
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var stringified = controllerContext.HttpContext.Request[bindingContext.ModelName];
if (string.IsNullOrEmpty(stringified))
return null;
return serializer.Deserialize(stringified, bindingContext.ModelType);
}
}
Затем зарегистрируйте ее в global.asax.cs как:
ModelBinders.Binders.Add(typeof(DocumentModel), new JsonModelBinder());
Теперь вы быне нужно использовать атрибут, и ваша DocumentModel будет связана правильно.Это будет означать, что вы всегда будете отправлять DocumentModel через JSON.