JSON.NET类名作为root

时间:2012-04-13 16:01:50

标签: knockout.js json.net asp.net-mvc-4 asp.net-web-api knockout-mapping-plugin

我正在使用ASP.NET MVC4 WebApi和Knockout.js。

我的模型包含 Pages ,其中包含1-N 控件。当我需要加载一个新的 Page 时,我将获取HTML视图和JSON序列化对象并将所有内容与KO放在一起。由于我的模型非常动态,我将使用KO映射插件,因此我不必定义所有的observable。

这是我的(非常简化的)模型:

public class Page
{
    public string Name { get; set; }
    public List<Control> Controls { get; set; }        
}

public abstract class Control
{
    public string Name { get; set; }
    public abstract string SayHi();
}

public class Form : Control
{
    public override string SayHi()
    {
        return string.Format("Hi, I'm form {0}", Name);
    }
}

public class Datagrid : Control
{
    public override string SayHi()
    {
        return string.Format("Hi, I'm datagrid {0}", Name);
    }
}

实际上,我得到了这个(用JSON.NET序列化):

[
{
    "Name":"pagina1",
    "Controls":
    [
        {"Name":"laTablita"},
        {"Name":"theForm"}
    ]
},
{
    "Name":"pagina2",
    "Controls":
    [
        {"Name":"elFormito"},
        {"Name":"theDatagrid"}
    ]
}
]

问题是我需要JSON将类名作为根键(因为KO.Mapping需要它),而JSON.NET序列化程序不包含它。

这就是我需要JSON的方式:

[
{
    "Name":"pagina1",
    "Controls":
    [
        "Datagrid":
        {
            "Name":"laTablita"
        },
        "Form":
        {
            "Name":"theForm"
        }
    ]
},
{
    "Name":"pagina2",
    "Controls":
    [
        "Form":
        {
            "Name":"elFormito"
        },
        "Datagrid":
        {
            "Name":"theDatagrid"
        },
    ]
}
]

1 个答案:

答案 0 :(得分:1)

如评论中所述,您所需的JSON不符合json规范。如果我了解您的需求,您希望确定每个控件的类型。有几种方法可以做到这一点。首先,JSON.NET可以使用具有属性JsonSerializerSettings的{​​{1}}对象。默认情况下,此项设置为“无”。如果将其设置为Object,则将包含类型名称。但是,这是.NET类型名称,可能不是您所追求的。

一种简单的方法是将TypeName属性添加到控件类,该属性返回表示类类型的字符串。

您返回的JSON看起来像。

TypeNameHandling

希望这有帮助。