如何使用jQuery发布一个包含数组的复杂对象(其中包含一个复杂对象数组)

3
我想使用jQuery发布一些带有ID和类别的产品。但是,当我添加类别时,在Microsoft.Web.Mvc.DataAnnotations.DataAnnotationsModelBinder.BindProperty(NullReferenceException)中出现错误。
默认的ModelBinder不应该能够绑定这个吗(没有ActionFilter或自定义ModelBinder)?
我尝试应用在另一个SO线程中找到的ActionFilter(进行反序列化),但它从未运行过。我还尝试了jQuery.ajaxSettings.traditional = true;、jQuery 1.3.2和1.4.2。在我找到的其他示例中,它们只发布ID、名称等,而不是另一个复杂对象数组。
有任何想法吗?

public class Product
{
    public int ID { get; set; }
    public Category[] Categories { get; set; }
}

public class Category
{
    public int ID { get; set; }
}

HTML

<input id="Product[0]_ID" name="Product[0].ID" type="hidden" value="9" />
<input id="Product[0]_Categories[0]_ID" name="Product[0].Categories[0].ID" type="hidden" value="99" />
<input id="Product[1]_ID" name="Product[1].ID" type="hidden" value="8" />
<input id="Product[1]_Categories[0]_ID" name="Product[1].Categories[0].ID" type="hidden" value="88" />

控制器

[JsonFilter(Parameter = "p")]
public JsonResult GetProductPrice([Bind(Prefix = "Product")] Product[] p)
{
    // TODO: Implement some checking...
    return Json(true);
}

jQuery

$.post(getProductPriceUrl, $("form").serializeArray(), function(data) {
    $("#Price").html(data);
});

JsonFilter

public class JsonFilter : ActionFilterAttribute
{
    public string Parameter { get; set; }
    //public Type JsonDataType { get; set; }

    private JavaScriptSerializer serializer;

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        serializer = new JavaScriptSerializer();

        if (filterContext.HttpContext.Request.ContentType.Equals("application/json"))
        {
            string inputContent;

            using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream))
            {
                inputContent = sr.ReadToEnd();
            }

            var result = serializer.Deserialize<Product>(inputContent);
            filterContext.ActionParameters[Parameter] = result;
        }
    }
}

文章 #1

__RequestVerificationToken=sz%2BLKCzTmdGMrH3TdOYipS5z%2BJ3uVyzBtJRZrruJoUohoGaH2O3DU5%2FcuU6hX1E%2F&Product%5B0%5D.ID=9&Product%5B0%5D.Categories%5B0%5D.ID=99&Product%5B1%5D.ID=8&Product%5B1%5D.Categories%5B0%5D.ID=88

提交 #2

__RequestVerificationToken=sz+LKCzTmdGMrH3TdOYipWTERHSdtCvGUhuw/dGIkgSL3rjcSLO7RJJN/rcssVwv&Product[0].ID=9&Product[0].Categories[0].ID=99&Product[1].ID=8&Product[1].Categories[0].ID=88

第三篇文章

[{"name":"__RequestVerificationToken","value":"sz+LKCzTmdGMrH3TdOYipcqr8WKC2eL7CRS5BZUtwzD60WkqfnjdeAcO3DQg5ss6"},{"name":"Product[0].ID","value":"9"},{"name":"Product[0].Categories[0].ID","value":"99"},{"name":"Product[1].ID","value":"8"},{"name":"Product[1].Categories[0].ID","value":"88"}]

你不应该需要一个ActionFilter。你能展示一下“POST”数据吗? - Craig Stuntz
嗯,帖子1和2是常规的键/值对,“帖子”3是JSON。你打算使用哪个,并且为什么要用两种方式?通常,在MVC中更喜欢标准的POST请求,因为JSON需要特殊处理。 - Craig Stuntz
我想使用标准的POST方法,但是经过几个小时的测试后,我没有成功,开始怀疑是否可能。因此,我尝试了JSON和“JsonFilter”,在阅读了一些SO线程并找到了这个解决方案后。 - Johan Olsson
标准的提交比提交JSON要容易得多,因为MVC支持前者“开箱即用”,而JSON提交支持是需要自己添加的。 - Craig Stuntz
好的,你有没有想法为什么我在使用标准POST时会出现错误呢?我不明白为什么简单的产品/类别示例不起作用。 - Johan Olsson
1个回答

0

我能想到两种方法来实现将复杂对象图发送回服务器并正确连接的目标。一种是你最初尝试的方式,即在HTML中表达关系。另一种是将子对象传递给部分视图。

因此,您可以为类别列表创建一个部分视图,并将Product.categories传递给它。这应该能够为您正确连接它。

这将会很方便。

@Html.Partial("_myCategoriesPartialView", Model.Categories)

当然,该视图将遍历集合。 我认为,如果您想以HTML的方式进行另一种方式,它应该是这样的。

<input id="Product[0]_ID" name="Product[0].ID" type="hidden" value="9" />

应该是

<input id="Product[0].ID" name="Product[0].ID" type="hidden" value="9" />,

但是确定的方法是查看Response.Form数据


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接