将JSON数组绑定到ASP.NET MVC 3中的列表的故障模型 [英] Trouble model binding a JSON array to a List in ASP.NET MVC 3

查看:128
本文介绍了将JSON数组绑定到ASP.NET MVC 3中的列表的故障模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在将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对象,如下所示:

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调用时会发生一些相当奇怪的事情.它击中了操作方法,我的List<DockState>中确实有项目.

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

我做错什么了吗?表格数据格式不正确吗?默认模型活页夹是否存在问题?

更新(测试达林·迪米特洛夫的答案)

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

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

好多了.但是现在当我调试时,列表中有零项.尽管我感谢您的努力:)

解决方案

尝试发送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 脚本. /p>

I am having trouble model binding a JSON array to a C# list in MVC 3.

I have an object called a DockState. It looks like this:

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

My action method accepts a list of dock states, like this:

public JsonResult SaveDockStates(List<DockState> dockStates)

On the client I am building an array of JSON objects that contain all the same properties as the C# DockState object. I am then assigning this array to a JSON object of its own with the property of the argument in the action method, like this:

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

Unfortunately something rather odd happens when the AJAX call is made. It hits the action method and my List<DockState> does have items in it.

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

However, the items in the list are all default. Meaning all their values are the default values, not the ones submitted in the request.

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

I'm not sure why the list contains the correct number of items, but all items appear to be nothing more than instantiated. Their properties were not set to the values in the JSON array. The request definitely contains the right data, as shown here:

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

Am I doing something wrong? Is the form data formatted incorrectly? Is there a problem with the default model binder?

Update (testing Darin Dimitrov's answer)

I discovered that JSON was being overridden by an unused old script. I have removed and now JSON.stringify is working fine. Here is the request payload.

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

Much better. However now when I am debugging my list has zero items in it. This did not seem to fix the problem, though I appreciate the effort :)

解决方案

Try sending a JSON request:

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

The JSON.stringify method is natively built into modern browsers. If you want to support legacy browsers you need to include the json2.js script to your page.

这篇关于将JSON数组绑定到ASP.NET MVC 3中的列表的故障模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆