KnockOutJs 对象未发布

发布于 2024-12-21 13:28:09 字数 3070 浏览 2 评论 0原文

我正在研究 KnockOutJs 示例,并且在使用 MVC3 时遇到一些发布问题。我的示例在使用整页回发时正确发布。当我尝试使用 jQuery Ajax 帖子保存时,我可以在使用 Firebug NET 查看器中看到该帖子为:

{gifts:[{"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);
                }
            }
        }

I am working through a KnockOutJs Sample and am having some posting problems with MVC3. My sample correctly posts when using a full page postback. When I try to save using an jQuery Ajax post, I can see the Post in the using Firebug NET viewer to be:

{ gifts:[{"GiftId":0,"Title":"sad","Price":3}] }

When I view the ControllerContext in the ModelBinder in MVC3, the form parameters are empty and the json does not bind. Any ideas as to what is happening?

I have tried a number of configurations but here is the jQuery posting code (currently hard-coded to a static value):

...

            $.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);
        }
        });

Edit: Here is the MVC3 action code for the Ajax update code

[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();
}

And the full postback code that works (from Steve Sanderson's example at
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");
}

using this custom model binder:

        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);
                }
            }
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

逆夏时光 2024-12-28 13:28:09

我的猜测是您从 Steve 的下载开始,它使用的是 MVC2。 MVC2 没有 JsonValueProvider[FromJson] 属性旨在与通过 ko.utils.postJson(完整回发)提交的 URL 编码 JSON 配合使用。当使用正确的内容类型(在 MVC3 中)通过 AJAX 发布 JSON 时,这不是必需的。

因此,最简单的方法是将项目升级到 MVC 3(简单方法此处)并从部分更新中删除 [FromJson] 属性。

工作副本此处

另一件非常小的事情:您的静态数据当前是无效的 JSON ('{gifts:[{"GiftId":0,"Title":"sad","Price":3}] }' )。 gifts 需要是“gifts”

My guess is that you started with Steve's download, which is using MVC2. MVC2 did not have the JsonValueProvider registered by default. The [FromJson] attribute was intended to work with URL-encoded JSON that was submitted via ko.utils.postJson (full postback). This is not necessary when posting JSON via AJAX with the correct content-type (in MVC3).

So, the easiest thing to do is upgrade your project to MVC 3 (easy way here) and remove the [FromJson] attribute from your partial update.

Working copy here.

One other really minor thing: your static data is currently invalid JSON ('{ gifts:[{"GiftId":0,"Title":"sad","Price":3}] }'). gifts would need to be "gifts"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文