【发布时间】:2011-12-17 01:52:12
【问题描述】:
我正在处理一个 KnockOutJs 示例,并且在使用 MVC3 时遇到了一些发布问题。使用整页回发时,我的示例正确发布。当我尝试使用 jQuery Ajax 帖子保存时,我可以在 using Firebug NET 查看器中看到帖子:
{ 礼物:[{"GiftId":0,"Title":"sad","Price":3}] }
当我在MVC3的ModelBinder中查看ControllerContext时,表单参数为空,json没有绑定。关于正在发生的事情有什么想法吗?
我尝试了许多配置,但这里是 jQuery 发布代码(当前硬编码为静态值):
...
$.ajax({
url: "/Home/PartialUpdate",
type: 'POST',
cache: false,
data: '{ gifts:[{"GiftId":0,"Title":"sad","Price":3}] }', //ko.toJSON({ gifts: this.gifts }),
dataType: 'json' ,
contentType: "application/json;",
success: function(result){
alert(result);
var data = ko.utils.parseJson(result);
this.gifts = ko.observableArray(data) ;
},
error:function(xhr,err){
alert("readyState: " + xhr.readyState+"\nstatus: "+xhr.status);
alert("responseText: " + xhr.responseText);
}
});
编辑:这里是 Ajax 更新代码的 MVC3 操作代码
[HttpPost]
public JsonResult PartialUpdate ([FromJson] IEnumerable<Gift> gifts)
{
gifts = gifts ?? new List<Gift>();
using (var context = new KnockOutContext())
{
// Add record if not in DB
foreach (var gift in gifts )
{
context.Entry(gift).State = (gift.GiftId == 0) ? EntityState.Added : EntityState.Modified;
}
// Delete records if not in ViewModel
foreach (var dbGift in context.Gifts)
{
if (gifts.SingleOrDefault(c => c.GiftId == dbGift.GiftId) == null)
context.Gifts.Remove(dbGift);
}
context.SaveChanges();
}
return GetGifts_Json();
}
以及有效的完整回发代码(来自 Steve Sanderson 在 http://blog.stevensanderson.com/2010/07/12/editing-a-variable-length-list-knockout-style/)
[HttpPost]
public ActionResult Index([FromJson] IEnumerable<Gift> gifts)
{
SaveGifts(gifts);
return RedirectToAction("Index");
}
使用此自定义模型绑定器:
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);
}
}
}
【问题讨论】:
-
您能从 MVC 添加您的操作代码吗?
-
自 MVC2 以来,您不需要
[FromJson]属性。 -
使用
dataType: 'json',您无需在回调中解析json。 Jquery 会为你做这件事。 -
如果我删除 [FromJson],这两个版本都不起作用。回发版本在绑定中有错误{“从类型'System.String'到类型'koListEditor.Models.Gift'的参数转换失败,因为没有类型转换器可以在这些类型之间转换。”}。这个项目是从 MVC2 开始的,所以它的配置可能有问题。
-
您需要使用注释掉的 ko.toJSON 作为 data 参数。
标签: jquery asp.net-mvc knockout.js