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

GouthamAnandAsked:
Who is Participating?
 
ricovoxConnect With a Mentor Commented:
Hi GouthamAnand,

I just want to clarify your question.

As you stated, when you serialize the class, you only want the 1st three properties to be written.

Now when you DEserialize, what exactly do you want? I.e. What do you expect the xml to contain?

I'm not sure that the solution sedgewick proposed will work for what you want.
XmlIgnore will cause the property to be completely ignored during BOTH serialization and deserialization.

So if you XML contains information about Category, Type, and Detail, then all of that information will be LOST (ignored) when you deserialize the XML.

If you don't care about that data loss, or if you don't expect the XML to contain any information except the 1st three properties, then you are okay with the previous suggestion.

But just to be clear, sedgwick's proposal will ONLY READ and WRITE the first three properties on serialization and deserialization. The other properties will be left as their default values when deserialized.
0
 
Meir RivkinFull stack Software EngineerCommented:
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; }
}
0
 
GouthamAnandAuthor Commented:
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.
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
GouthamAnandAuthor Commented:
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!
0
 
GouthamAnandAuthor Commented:
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.
0
 
ihardingConnect With a Mentor Commented:
If you need more fine grained control over the serialize and de-serialize process, implement the IXmlSerializable interface.
0
 
ricovoxConnect With a Mentor Commented:
Hi GouthamAnand,

I think I understand what you are saying, and if that is the case then I was right before. XmlIgnore will NOT work for you because when you deserialize it will cause the input data to be ignored unless the input and output xml format is the same (which is NOT the case as you have stated).

So the answer is as iharding suggested. You have to implement IXMLSerializable. I was getting to that point, but I just wanted to verify that you needed that much control before I suggested it.

Why don't you post some examples of the input and output xml and I can write the IXmlSerializable interface methods you need. You can abbreviate the xml if you want. I just need a good, specific example so I can give you an example of the type of code you need.
0
 
GouthamAnandAuthor Commented:
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

0
 
GouthamAnandAuthor Commented:
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/>
0
 
GouthamAnandAuthor Commented:
Thanks a lot.
0
 
ricovoxCommented:
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.
0
 
ricovoxCommented:
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.
0
 
ricovoxCommented:
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.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.