1

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

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

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

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"
        },
    ]
}
]
4

1 回答 1

1

如评论中所述,您所需的 JSON 不符合 json 规范。如果我了解您的需求,您想确定每个控件的类型。有几种方法可以做到这一点。首先 JSON.NET 可以采用JsonSerializerSettings具有属性的对象TypeNameHandling。默认情况下,这设置为无。如果将其设置为 Object 类型名称将被包括在内。但是,这是 .NET 类型名称,可能不是您想要的。

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

您返回的 JSON 看起来像这样。

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

希望这可以帮助。

于 2012-04-13T22:33:20.133 回答