我有以下表格:
<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>
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?
}
现在,如何对 MVC 3 应用程序执行表单 POST 并获取反序列化类?
最佳答案
如果您通过 AJAX 发布它并将内容类型设置为 JSON,那么 MVC 3 将能够在您的 Controller 操作中正确绑定(bind)它。
$.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 不会自动将其绑定(bind)到您的模型,因为内容类型将是 application/x- www-form-urlencoded。
Steve Sanderson 有一个较旧的示例,演示如何在 Controller 操作中正确绑定(bind)提交的 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)
此外,如果您不喜欢必须使用该属性,那么您实际上可以注册一个类型以始终使用某个模型绑定(bind)器。
您可以创建一个如下所示的模型绑定(bind)器:
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 将被正确绑定(bind)。这意味着您将始终通过 JSON 发送 DocumentModel。
关于asp.net-mvc - 如何对 MVC 3 应用程序执行表单 POST 并获取反序列化类?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6793377/