将 JSON 数组绑定到 ASP.NET MVC 3 中的列表的故障模型

Posted

技术标签:

【中文标题】将 JSON 数组绑定到 ASP.NET MVC 3 中的列表的故障模型【英文标题】:Trouble model binding a JSON array to a List in ASP.NET MVC 3 【发布时间】:2011-11-06 06:48:32 【问题描述】:

我在将 JSON 数组模型绑定到 MVC 3 中的 C# 列表时遇到问题。

我有一个名为DockState 的对象。它看起来像这样:

[Serializable]
public class DockState

    public bool Closed  get; set; 
    public bool Collapsed  get; set; 
    public string DockZoneID  get; set; 
    public int ExpandedHeight  get; set; 
    public Unit Height  get; set; 
    public int Index  get; set; 
    public Unit Left  get; set; 
    public bool Pinned  get; set; 
    public bool Resizable  get; set; 
    public string Tag  get; set; 
    public string Text  get; set; 
    public string Title  get; set; 
    public Unit Top  get; set; 
    public string UniqueName  get; set; 
    public Unit Width  get; set; 

我的操作方法接受停靠状态列表,如下所示:

public JsonResult SaveDockStates(List<DockState> dockStates)

在客户端上,我正在构建一个 JSON 对象数组,其中包含与 C# DockState 对象相同的所有属性。然后,我将这个数组分配给它自己的 JSON 对象,并使用 action 方法中的参数属性,如下所示:

function get_allDockStates()

    var allRadDocks = []; // declare array.
    var allRadControls = $telerik.radControls; // use telerik API to obtain all controls.

    // loop through all telerik controls.
    for (var i = 0; i < allRadControls.length; i++)
    
        var element = allRadControls[i];

        // Check if control is a rad dock element.
        if (Telerik.Web.UI.RadDock && element instanceof Telerik.Web.UI.RadDock)
        
            // Build a JSON object containing the same properties as the C# DockState
            // object. Leaving out a couple that should just be null anyway. Add new
            // JSON object to array.
            Array.add(allRadDocks,
            
                UniqueName: element._uniqueName,
                DockZoneID: element._dockZoneID,
                Width: element._width,
                Height: element._height,
                ExpandedHeight: element._expandedHeight,
                Top: element._top,
                Left: element._left,
                Resizable: element._resizable,
                Closed: element._closed,
                Collapsed: element._collapsed,
                Pinned: element._pinned,
                Title: element._title,
                Index: element._index
            );
        
    
    // Return the array.
    return allRadDocks;


// This function is fired by the rad dock controls when they are moved.
function positionChanged(sender, e)

    // obtain the array of dock states.
    var dockStates = get_allDockStates();
    // Make ajax call to MVC action method to save dock states.
    jQuery.ajax(
        data:  dockStates: dockStates ,
        type: 'POST',
        dataType: 'json',
        url: '/AjaxServices/DashboardService/SaveDockStates'
    );

不幸的是,在进行 AJAX 调用时发生了一些相当奇怪的事情。它点击了 action 方法,我的 List&lt;DockState&gt; 里面确实有项目。

http://www.codetunnel.com/content/images/dockStateListInstantiated.jpg

但是,列表中的项目都是默认的。这意味着它们的所有值都是默认值,而不是在请求中提交的值。

http://www.codetunnel.com/content/images/dockStatesDefaultValues.jpg

我不确定为什么列表包含正确数量的项目,但所有项目似乎都只是实例化的。它们的属性未设置为 JSON 数组中的值。请求肯定包含正确的数据,如下所示:

http://www.codetunnel.com/content/images/dockStatesFormData.jpg

我做错了吗?表单数据的格式是否错误?默认模型绑定器有问题吗?

更新(测试 Darin Dimitrov 的答案)

我发现 JSON 被一个未使用的旧脚本覆盖。我已删除,现在JSON.stringify 工作正常。这是请求负载。

http://www.codetunnel.com/content/images/dockStatesJsonStringify.jpg

好多了。但是现在当我调试时,我的列表中有零个项目。这似乎并没有解决问题,虽然我很感激你的努力:)

【问题讨论】:

【参考方案1】:

尝试发送 JSON 请求:

jQuery.ajax(
    // TODO: Never hardcode urls like this => always use URL helpers
    // when you want to generate an url in an ASP.NET MVC application
    url: '/AjaxServices/DashboardService/SaveDockStates',
    type: 'POST',
    data: JSON.stringify( dockStates: dockStates ),
    contentType: 'application/json; charset=utf-8',
    success: function(result) 
        // TODO: process the results
    
);

JSON.stringify 方法原生内置于现代浏览器中。如果您想支持旧版浏览器,您需要在页面中包含 json2.js 脚本。

【讨论】:

@Alex Ford,您的请求负载完全搞砸了。你从哪里得到这个JSON.stringify 函数?删除它并尝试使用现代浏览器中内置的那个。 @Alex Ford,我在回答中提供了一个链接:github.com/douglascrockford/JSON-js。但正如我所说:首先在没有它的情况下进行测试 => 在现代浏览器中。就 url 而言,正如我所说的,应该始终使用帮助程序生成 url。 @Alex Ford,你用的是什么浏览器?如果您使用的是最新版本的 Chrome,这是不可能的。它内置了 JSON.stringify 方法。确保您没有在某处覆盖它。 我不能在 Web 表单中使用 mvc 助手...可以吗? 好的,我修复了 JSON.stringify 并用结果更新了我的问题。请求负载看起来好多了,但它似乎对模型绑定器没有帮助。

以上是关于将 JSON 数组绑定到 ASP.NET MVC 3 中的列表的故障模型的主要内容,如果未能解决你的问题,请参考以下文章

使用防伪令牌将 JSON 模型发布到 ASP.Net MVC3

在 ASP.NET MVC Core 2 中使用 MetadataPropertyHandling 模型绑定 JSON 数据

如何将带有 JSON、jQuery 的复杂对象数组发布到 ASP.NET MVC 控制器?

ASP.Net MVC:具有动态列的 Jquery 数据表与 JSON 绑定

将 JSON 从视图发送到控制器 ASP.NET MVC 会给出空值

ASP.NET MVC ajax数组,模型绑定问题。