C#Newtonsoft.JSON内部对象映射

时间:2017-11-30 09:31:38

标签: c# json.net

我最近遇到了一个问题,我的json格式只是1层,但为了重用我的模型,我想按照下面给出的例子格式化它们。

我当然可以在构造函数中转储json并自己格式化,但我希望能让我的模型更加抽象。

using System;
using Newtonsoft.Json;  
using Newtonsoft.Json.Linq;

public class Program
{
    public static void Main()
    {
        string json = @"
        {
            ""Name"" : ""Blaa"",
            ""Age"" : 1,
            ""EyeColor"": ""Blue""
        }";

        JObject jsonObj = JObject.Parse(json);
        Person person = jsonObj.ToObject<Person>();

        Console.WriteLine(person.Name);
        Console.WriteLine(person.Age);
        Console.WriteLine(person.Eyes.Color);
    }
}

class Person
{
    [JsonProperty("Name")]
    public string Name { get; set; }

    [JsonProperty("Age")]
    public int Age { get; set; }

    public Eyes Eyes{ get; set; }
}

class Eyes
{
    [JsonProperty("EyeColor")]
    public string Color{ get; set; }
}

1 个答案:

答案 0 :(得分:2)

如果您想将数据传输对象与域模型分开,这可能是有用的。

虽然可以单独在DTO中解决这个问题,但它所需的自定义不允许轻松重用,也不允许从示例JSON生成DTO。

您宁愿让DTO与JSON匹配:

public class PersonDto
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string EyeColor { get; set; }
}

然后将其映射到域模型中:

public class Person
{
    public string Name { get; set; }

    public int Age { get; set; }

    public Eyes Eyes { get; set; }

    // Empty ctor for various reasons
    public Person() { } 

    public Person(PersonDto dto)
        : this()
    {
        Name = dto.Name;
        Age = dto.Age;
        Eyes = new Eyes
        {
            Color = dto.EyeColor
        };
    }
}

public class Eyes
{
    public string Color{ get; set; }
}

例如,也可以使用AutoMapper完成映射。

或者你可以通过一个被忽略的属性来解决它,但是返回或保湿Eyes实例:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    [JsonIgnore]
    public Eyes Eyes { get; set; }

    public string EyeColor 
    {
        get { return Eyes.Color; }
        set { Eyes.Color =  value; }
    }

    public Person()
    {
        this.Eyes = new Eyes();
    }
}

注意我省略了JsonProperty属性,如果属性名称与JSON字段匹配,则不需要这些属性&#39;名。