JSON.NET class name as root

2019-08-03 04:54发布

I'm working with ASP.NET MVC4 WebApi and Knockout.js.

My model consists of Pages that contain 1-N Controls. When I need to load a new Page, I will fetch the HTML View and the JSON serialized object and put all together with KO. As my model is very dynamic, I'm going to use the KO mapping plugin so I don't have to define all the observables.

Here is my (very simplified) model:

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

Actually, I'm getting this (serialized with JSON.NET):

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

The problem is that I need the JSON to have class names as root key (because KO.Mapping needs it that way), and JSON.NET serializer doesn't include it.

This is how I need the JSON:

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

1条回答
我想做一个坏孩纸
2楼-- · 2019-08-03 05:21

As mentioned in the comments your required JSON doesn't fit the json specification. If I understand what you need, you would like to identify what type each control is. There are a couple of ways to do this. First JSON.NET can take a JsonSerializerSettings object that has a property TypeNameHandling. By default this is set to None. If you set it to Object the type name will be included. However, this is the .NET type name, probably not what you are after.

A simple approach would be to add a TypeName property to your control class that returns a string representing the type of the class.

Your returned JSON will look something like.

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

Hope this helps.

查看更多
登录 后发表回答