Link to home
Start Free TrialLog in
Avatar of GouthamAnand
GouthamAnand

asked on

Serialize and Deserializing of an object.

I have a class (Challenge) and I am serializing and desirializing it.

While serializing it has to serialize only few members, and while deserialzing it will get different set. But all are members of the same class.

Suppose my class is having 6 members as shown below. While serialising I want to serialize only 1st 3 members - ParentCaseId , CaseId, UserId.
While desirializing I get other 3 members (Category, Type, Detail).

How to achieve this?


public class Challenge
{
    [XmlElement("ParentCaseId")]
    public int ParentCaseId { get; set; }

    [XmlElement("CaseId")]
    public int CaseId { get; set; }

    [XmlElement("UserId")]
    public string UserId { get; set; }

    [XmlElement("Category")]
    public string Category { get; set; }

    [XmlElement("Type")]
    public string Type { get; set; }

    [XmlElement("Detail")]
    public string Detail { get; set; }
}

Open in new window

Avatar of Meir Rivkin
Meir Rivkin
Flag of Israel image

just add XmlIgnore attribute on those you wish not to serialize:

public class Challenge
{
    [XmlElement("ParentCaseId")]
    public int ParentCaseId { get; set; }
 
    [XmlElement("CaseId")]
    public int CaseId { get; set; }
 
    [XmlElement("UserId")]
    public string UserId { get; set; }
 
    [XmlIgnore("Category")]
    public string Category { get; set; }
 
    [XmlIgnore("Type")]
    public string Type { get; set; }
 
    [XmlIgnore("Detail")]
    public string Detail { get; set; }
}
Avatar of GouthamAnand
GouthamAnand

ASKER

Ok , but to deserialize those what I need to mention? While desirializing I want to desirialize those 3 which I declared as XmlIgnore for serializing and Ignore the 3 serialized.
ASKER CERTIFIED SOLUTION
Avatar of ricovox
ricovox
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
My requirment is like this.

I get an XML as input string. The tags of that XML are only few members of my class. So I have to deserialize the incoming XML to my object.

After that I have send an XML as output. The tags of this XML also part of the same clase but are totally different from the ones which I got as input.
Hope I explained properly!

Generally serialization and deserialization happens on all or some of the members of the class , but in both the cases the members will be same. In my case the members that get serialized are different from those which are getting deserialized. That is my requirement. Hope you got  now!
Object or Class is same. but I get the XML as input which contians only few members of the class.

And I have to return an XML as output which are totally different elements of the same class/object.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Simple example I will give.

I am selling a product to you and I said it is $50. You have asked (or bargained) with me and said that you want to pay $40. Then again I said make it $45.

This conversation is taking place in the form of XML and this entire exchange of information (or discussion) is about the same product. Hope this example suites well.

Because below XML is the input for me and explaining it is very difficult for me, but the concept what I explained you above is same in my application.

Now you can explain I hope.
<?xml version="1.0" encoding="iso-8859-1"?>  
  <Request
    SourceSystem="ABC"
    xmlns="map.xml.lmn.pqrs.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="map.xml.lmn.pqrs.com Request.xsd">
    <Challenge>
      <ParentCaseId>1234</ParentCaseId>
      <CaseId>1234</CaseId>
      <UserId>nk34</UserId>
      <Category>My Category</Category>
      <Type>My Type</Type>
      <Detail>My Detail</Detail>
      <Status>New/Open</Status>
      <ChallengeType>Not Sure What This Is</ChallengeType>
      <AccountId>012345</AccountId>
      <InstrumentId>my instrument id</InstrumentId>
      <SecurityId>MySecurityId</SecurityId>
      <SecurityType>SecurityType</SecurityType>
      <PriceDate>12/31/9999</PriceDate>
      <PricingPoint>My Pricing POint</PricingPoint>
      <ManagerPrice>0.000023</ManagerPrice>
      <ManagerPriceSource>My Preferred Vendor</ManagerPriceSource>
      <Currency>USD</Currency>
      <NewPrice>0.000023</NewPrice>
      <NewPriceSource>0.000023</NewPriceSource>
      <ResolutionCode>0.000023</ResolutionCode>
      <PriceType>Price Type</PriceType>
      <Country>IND</Country>

Open in new window

Simplifying my requirement to very simple, our XMLs will be like this.

<Challenge>
<Product>xyz</Product>
<SellersPrice>50</SellersPrice>
<Challenge/>
My business object Challenge will be serialized to above XML.

Below XML I want to deserialize to my business object.
<Challenge>
<Product>xyz</Product>
<BuyersPrice>40<BuyersPrice>
<Challenge/>
Thanks a lot.
I see,

So you for example, the object has these properties:

class Challenge {
   public string Product
   public single Price
}

Open in new window


and you want it to serialize to give the following XML:
<Challenge>
<Product>xyz</Product>
<SellersPrice>50</SellersPrice>
<Challenge/>

(where the Price property is serialized to the SellersPrice xml tag)

And when you recieve an XML response it will be in the following form:
<Challenge>
<Product>xyz</Product>
<BuyersPrice>50</BuyersPrice>
<Challenge/>

When you deserialize this, you want the BuyersPrice xml tag to be deserialized into the Price property.

Does that sound about right?
If so, you might be able to use a slighly simpler method of XMLSerialization than fully implementing IXMLSerializer.
You can use the "Choice" advanced mapping technique outlined here:
http://msdn.microsoft.com/en-us/magazine/cc164135.aspx

Then your class would look something like this:

public class Challenge {
   public string Product { get; set;}

   [XmlElement("SellersPrice")]
   [XmlElement("BuyersPrice")]
   [XmlChoiceIdentifier("PriceType")]
   public float Price { get; set;}
   
   [XmlIgnore]
   public ChallengePriceType PriceType {get; set;}
}

public enum ChallengePriceType {
   BuyersPrice,
   SellersPrice
}

Open in new window


The important thing to notice is that the "Price" property has two "XmlElement" attributes: one for EACH of the possible Xml tags (BuyersPrice and SellersPrice) and we have added the XmlChoiceIdentifier attribute.

The XmlChoiceIdentifier tells the XMLSerializer that the Price property could be stored in XML as EITHER tag mentioned above. And it also tells the XMLSerializer that it can determine which tag should be used based on another property in the class, called "PriceType". I created a new enum to hold all valid values for PriceType. (The enum values must match the actual XML tags.)
Notice also that the PriceType has the XMLIgnore attribute, so it won't actually be written to the xml.

So here's how you would use it:

//To Serialize:
var x = new Challenge();
x.Product = "xyz";
x.Price = 50f;
x.PriceType = ChallengePriceType.SellersPrice;

XmlSerializer s = new XmlSerializer(typeof(Challenge));
FileStream fs = new FileStream("serizlize.xml", FileMode.Create); //or some other stream
s.Serialize(fs, x);
fs.Close();

Open in new window


This will output the following XML:

<Challenge>
   <Product>xyz</Product>
   <SellersPrice>50</SellersPrice>
<Challenge/>

Open in new window



---------------------------------------------
Now let's see how deserialization would work.

Assume we received the following XML:
<Challenge>
   <Product>xyz</Product>
   <BuyersPrice>40</BuyersPrice>
<Challenge/>

Open in new window


We deserialize it as follows:

    XmlSerializer s = new XmlSerializer(typeof(Challenge));
    FileStream fs = new FileStream("deserialize.xml", FileMode.Open);
    Challenge x = (Challenge)s.Deserialize(fs);
    fs.Close();
    System.Diagnostics.Debug.WriteLine("{0}: {1}", x.PriceType, x.Price);

Open in new window


This would output the following:
BuyersPrice: 40

So hopefully now you get the idea.
When the class is Serialized, the XmlSerializer will READ the "PriceType" property and it will use that to determine whether it should write out the Price property as a "SellersPrice" or "BuyersPrice" tag in the xml. You must SET the PriceType property BEFORE you serialize the class.

When the class is DESerialized, the XmlSerializer will take the input Xml and will SET the PriceType property to reflect which tag it found (e.g. SellersPrice or BuyersPrice). You can test the PriceType property after you deserialize it determine whether it is a Buyers Challenge or a Sellers challenge.
Dear GouthamAnand,

I hope you will consider upgrading my answer from a C to an A, based on the additional information I provided.
I would have provided it before, but I did not have time to write it all before you marked the question as answered.