如何将列表A设置为等于列表B,其中在B上不存在A

时间:2017-02-15 11:20:08

标签: c# json list serialization

我有一个类型为人的C#列表。此列表需要转换为JSON数据格式。 Person C#类看起来像这样:

 public class Person
    {
        public int ID { get; set; }
        public static int PSID = 1;
        public string name { get; set; }
        public string nameToken { get; set; }
        public double DOB { get; set; }
        public List<Award> awards { get; set;  }
        public List<Link> links { get; set; }

        public Person()
        {

            awards = new List<Award>();
            links = new List<Link>();
            ID = PSID;
            PSID++;
        }


    }

因为我需要将Person类型的C#列表转换为JSON。我在C#中创建了另一个名为PersonJS的类。它与Person C#类完全相同,唯一的区别是我删除了JSON前端中不需要的一些属性。即:nameToken,PSID。

public class PersonJS
{

    public int ID { get; set; }

    public string name { get; set; }

    public double DOB { get; set; }

    public List<AwardJS> awards { get; set; }

    public List<Link> links { get; set; }


}

PersonJS的一个属性是名为awards的List,类型为AwardJS。下面出现一个问题,因为我尝试将Person.awards List等于PersonJS.awards List。但是,它们的类型不同,因此无法使两个列表相等。我之所以将它们等同于不同类型,是因为JSON数据不需要我在C#中使用的所有属性。所以我获得了两个奖项和AwardJS。唯一的区别是Award包含一个名为filmWebToken的属性,而AwardJS则没有。

public class Award
  {

    public int filmID { get; set; }

    public int categoryID { get; set; }

    public string filmWebToken { get; set; }
}



public class AwardJS
{

    public int filmID { get; set; }

    public int categoryID { get; set; }

}

在我的代码中,我迭代了 Person 类型的C#列表中的所有属性,并尝试创建personjs对象并将其添加到 PersonJS C#列表中。 PersonJS 列表将以JSON的形式返回到前端。但是,因为PersonJS类中的奖励属性与Person中的奖励属性不同,我得到错误“无法隐式转换类型AwardJS到奖励”。我收到此错误的原因是因为PersonJS不包含Person类中存在的 filmWebToken 。我不希望filmWebToken位于PersonJS列表中,因为它不是我的JSON数据中的属性。但是,由于Person.Award中有属性字段,我仍然希望访问:filmID和CategoryID如何忽略/绕过filmWebToken字段。这就是我的尝试:

 List<Person> allPersons = DataRepository.GetAllPersons(); // contains the C# data 
        List<PersonJS> personjs = new List<PersonJS>(); // empty to start with

        foreach (var person in allPersons)
        {
            foreach (var award in person.awards) 
            {
                personjs.Add(
                    new PersonJS
                    {
                        ID = person.ID,
                        links = person.links, 
                        name = person.name,
                        DOB = person.DOB,
                        awards = person.awards // The types are not equal: Person contains filmWebToken whereas PersonJS does not


                    });



            }


        }

2 个答案:

答案 0 :(得分:2)

ToAwardJS中添加名为Award的方法:

public AwardJS ToAwardJS() {
    return new AwardJS { filmID = this.filmID, categoryID = this.categoryID };
}

然后在创建PersonJS对象时,执行:

new PersonJS
{
    ID = person.ID,
    links = person.links, 
    name = person.name,
    DOB = person.DOB,
    awards = person.awards.Select(x => x.ToAwardJS()).ToList(),
});

答案 1 :(得分:0)

您使用的是什么序列化程序?大多数提供属性来指定要包含在序列化中的成员。例如,DataContractJsonSerializer使用[DataContract][DataMember]。我认为Json.net使用[JsonIgnore]。不需要多个班级。

void Main()
{
    var jsSer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(Person));

    var p = new Person {
        ID = 1,
        name = "John",
        DOB = 1234.5,
        nameToken = "token"
    };

    string result = null;
    using (var ms = new MemoryStream())
    {
        jsSer.WriteObject(ms, p);
        byte[] json = ms.ToArray();
        ms.Close();

        result = Encoding.UTF8.GetString(json, 0, json.Length);
    }

    Console.WriteLine(result);
}

[DataContract]
public class Person
{
    //included
    [DataMember]
    public int ID { get; set; }
    [DataMember]
    public string name { get; set; }
    [DataMember]
    public string nameToken { get; set; }
    [DataMember]
    public double DOB { get; set; }

    //ignored
    public static int PSID = 1;
    public List<string> awards { get; set;  }
    public List<string> links { get; set; }

    public Person()
    {

        awards = new List<Award>();
        links = new List<Link>();
        ID = PSID;
        PSID++;
    }
}

结果:

  

{ “DOB”:1234.5, “ID”:1, “名称”: “约翰”, “nameToken”: “令牌”}