简体   繁体   中英

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

I am making a Travel app project consisting of a backend coded in PHP and a UWP app (frontend) coded in C#.

Following represent the "Holiday Package" class implemented in 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++;
        }
    }
}

Following is the JSON string returned by the backend

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

I want to deserialize the above JSON string into the "Packages" class thereby setting its "PackageID", "Name", "Destination", "Description", "Duration" and "BasePrice" properties ie I want to set only a subset of properties using web data

How to implement the above solution using the DataContractJsonSerializer class?

Do I need to Add/Modify any Constructor?

DataContractJsonSerializer will never call a parameterized constructor. Thus, as it stands, since your Packages type lacks a parameterless constructor, it throws an exception because it does not know how to construct an instance of such a type.

You have two ways to enble DataContractJsonSerializer to construct your object. Firstly, you can add a parameterless constructor. It could even be private:

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

Alternatively, if you don't want even a private parameterless constructor, you can mark your type with [DataContract] and [DataMember] attributes:

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

This works because, for data contract types, the data contract serializer does not call any constructor at all .

Having implemented either of these options for Packages (and, probably, HotelInPackage , which is not included in the question), you can now deserialize your JSON. Only those properties actually present in the JSON will be set.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM