【问题标题】:How to set list A equal to list B, where on B a property does not exist which does exist on A如何将列表 A 设置为等于列表 B,其中 B 上不存在 A 上存在的属性
【发布时间】:2017-02-15 11:20:07
【问题描述】:

我有一个 Person 类型的 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# 中使用的所有属性。所以我做了两个类Award和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 类中的 Award 属性与 Person 中的 Award 属性不同,我收到错误 “无法将类型 AwardJS 隐式转换为 Award”。我收到此错误的原因是因为 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


                    });



            }


        }

【问题讨论】:

  • 看起来您只需要将 Award 类型的相关部分投影到新的 AwardJS 实例中,这与您将每个 Person 投影到新的 PersonJS 的方式非常相似。 LINQ 有一个很好的方法来解决这个问题,使用 Select 投影值的方法。
  • Automapper 非常适合这类事情。 automapper.org
  • @AdamHouldsworth 你能举个例子吗
  • @hoChay Sweeper 的回答显示了一种方法。
  • 另外,您可以只使用 [JsonIgnore] 属性标记不应该序列化的属性。

标签: c# json list serialization


【解决方案1】:

Award中添加一个名为ToAwardJS的方法:

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

【讨论】:

    【解决方案2】:

    您使用的是什么序列化程序?大多数提供属性来指定要包含在序列化中的成员。例如,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,"name":"John","nameToken":"token"}

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-12
      • 1970-01-01
      • 2010-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多