pil*_*ice 3 asp.net-mvc post object-serialization knockout.js
我有以下表格:
<form id="MakeDocumentForm" name="MakeDocumentForm"
action="Document/GetWordDocument" method="post"
enctype="application/json">
<button type="submit" style="float:right;">Make Word Document</button>
<textarea id="hiddenJson"
name="hiddenJson"
data-bind="text: ko.toJSON(viewModel.selectedDocument)"
rows="5" cols="100"
style="visibility:hidden;" >
</textarea>
</form>
Run Code Online (Sandbox Code Playgroud)
该data-bind
属性是knockoutjs - 但这并不重要,textarea正确包含作为序列化对象的JSON.
[HttpPost]
public void GetWordDocument(DocumentModel hiddenJson)
{
//hiddenJson is not a correctly populated instance of my DocumentModel class
//any MVC experts know what I am doing wrong?
}
Run Code Online (Sandbox Code Playgroud)
现在,我如何对MVC 3应用程序执行表单POST并获取反序列化的类?
如果您通过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"); }
});
Run Code Online (Sandbox Code Playgroud)
但是,如果在您的示例中,您想要执行包含JSON的普通表单帖子,那么您需要做更多工作,因为MVC3不会自动将其绑定到您的模型,因为内容类型将是application/x- WWW的形式,进行了urlencoded.
Steve Sanderson有一个较旧的示例,它演示了如何在控制器操作中正确绑定提交的JSON数据:http://blog.stevensanderson.com/2010/07/12/editing-a-variable-length-list-knockout-样式/
它的要点是他创建了一个名为"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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后,动作看起来像:
[HttpPost]
public ActionResult Index([FromJson] IEnumerable<GiftModel> gifts)
Run Code Online (Sandbox Code Playgroud)
此外,如果您不喜欢必须使用该属性,那么您实际上可以注册一个类型以始终使用某个模型绑定器.
您可以创建一个模型绑定器,如下所示:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,在global.asax.cs中注册它,如:
ModelBinders.Binders.Add(typeof(DocumentModel), new JsonModelBinder());
Run Code Online (Sandbox Code Playgroud)
现在,您不需要使用属性,您的DocumentModel将被正确绑定.这意味着您将始终通过JSON发送DocumentModel.
归档时间: |
|
查看次数: |
1306 次 |
最近记录: |