如何使用 DataContractJsonSerializer 使用从 Web 获取的数据(以 JSON 的形式)设置对象的属性子集

How to set a subset of properties of an object using data obtained from web (in form of JSON) using DataContractJsonSerializer

我正在制作一个 Travel 应用程序项目,其中包含一个用 PHP 编码的后端和一个用 C# 编码的 UWP 应用程序(前端)。

以下代表"Holiday Package"class用C#

实现
 public class Packages
{
    public string PackageID { get; set; }
    public string Name { get; set; }
    public string Destination { get; set; }
    public string Description { get; set; }
    public int Duration { get; set; }
    public float BasePrice { get; set; }
    public List<string> Images { get; set; }

    public HotelInPackage Hotel { get; set; }

    public string TransportType { get; set; }

    public Packages(string packageID,string name,string destination,string description,int duration,float basePrice,List<string> images)
    {
        PackageID = packageID;
        Name = name;
        Destination = destination;
        Description = description;
        Duration = duration;
        BasePrice = basePrice;
        Images = images;
    }

    public void HotelConstruct(string hotelID,string name,int cat)
    {
        Hotel = new HotelInPackage(hotelID, name, cat);
    }

    public void SetTransport(string transportType)
    {
        TransportType = transportType;
    }

    public void ChangeImageName()
    {
        int i = 0;
        while(i<Images.Count)
        {
            Images[i] = string.Format("Assets/CitiesPlaceholder/{0}.jpg",Images[i]);
            i++;
        }
    }
}

以下是后台返回的JSON字符串

{
"PackageID":"P280",
"Name":"Sigapore Dreams",
"Destination":"Singapore",
"Description":"lorem ipsum,dolor sit amet",
"Duration":5,
"BasePrice":999.2
}

我想将上面的 JSON 字符串反序列化为 "Packages" class 从而设置它的 "PackageID", "Name", "Destination", "Description"、"Duration" 和 "BasePrice" 属性,即我只想使用网络数据设置属性的子集

如何使用DataContractJsonSerializer实现上述解决方案class?

我需要Add/Modify任何构造函数吗?

DataContractJsonSerializer 永远不会调用参数化构造函数。因此,就目前而言,由于您的 Packages 类型缺少无参数构造函数,它会抛出异常,因为它不知道如何构造此类类型的实例。

您有两种方法可以 DataContractJsonSerializer 构建您的对象。首先,您可以添加一个无参数构造函数。它甚至可以是私有的:

public class Packages
{
    public string PackageID { get; set; }
    public string Name { get; set; }
    public string Destination { get; set; }
    public string Description { get; set; }
    public int Duration { get; set; }
    public float BasePrice { get; set; }
    public List<string> Images { get; set; }

    public HotelInPackage Hotel { get; set; }

    public string TransportType { get; set; }

    Packages()
    {
        Debug.WriteLine("Calling private constructor of " + GetType().FullName);
    }

    public Packages(string packageID, string name, string destination, string description, int duration, float basePrice, List<string> images)
    {
        PackageID = packageID;
        Name = name;
        Destination = destination;
        Description = description;
        Duration = duration;
        BasePrice = basePrice;
        Images = images;
    }
}

或者,如果您甚至不需要私有无参数构造函数,您可以使用 [DataContract] and [DataMember] 属性标记您的类型:

[DataContract]
public class Packages
{
    [DataMember]
    public string PackageID { get; set; }
    [DataMember]
    public string Name { get; set; }
    [DataMember]
    public string Destination { get; set; }
    [DataMember]
    public string Description { get; set; }
    [DataMember]
    public int Duration { get; set; }
    [DataMember]
    public float BasePrice { get; set; }
    [DataMember]
    public List<string> Images { get; set; }

    [DataMember]
    public HotelInPackage Hotel { get; set; }

    [DataMember]
    public string TransportType { get; set; }

    public Packages(string packageID, string name, string destination, string description, int duration, float basePrice, List<string> images)
    {
        PackageID = packageID;
        Name = name;
        Destination = destination;
        Description = description;
        Duration = duration;
        BasePrice = basePrice;
        Images = images;
    }
}

这是有效的,因为对于数据协定类型,数据协定序列化程序 does not call any constructor at all

Packages(可能还有 HotelInPackage,这不包括在问题中)实施了这些选项中的任何一个,您现在可以反序列化您的 JSON。只有 JSON 中实际存在的属性才会被设置。