Reputation: 1903
Is it possible to hide a class' data member from client applications but still serialize with XmlSerializer?
The context is that I'm getting an address in pieces but need to concatenate many of those pieces into a single string before serializing the object to XML and passing it along to something else.
The address class is in turn part of a larger class so simply inheriting and adding this bit is more complicated were it not nested and my need isn't great enough to warrant writing a custom serializer.
Sample:
[DataContract]
public class Address
{
[DataMember()]
public string City
[DataMember()]
public string State
[DataMember()]
public string StreetDirection
[DataMember()]
public string StreetName
[DataMember()]
public string StreetNumber
[DataMember()]
public string StreetSuffix
[DataMember()]
public string Unit
[DataMember()]
public string Zip
[IgnoreDataMember()]
[Serializable]
public string AddressLine1
}
Basically, I want to have a placeholder (AddressLine1) where I can put the concatenation of StreetXXX properties before passing along (and it's already if the receiver sees the individual pieces).
Edit - add example Input would be something like:
<Address>
<StreetNumber>123</StreetNumber>
<StreetDirection>S.</StreetDirection>
<StreetName>Main</StreetName>
<StreetSuffix>St.</StreetSuffix>
<Unit>207</Unit>
<City>Denver</City>
<State>CO</State>
<Zip>80123</Zip>
</Address>
But I'd want to wind up serializing to:
<Address>
<StreetNumber>123</StreetNumber>
<StreetDirection>S.</StreetDirection>
<StreetName>Main</StreetName>
<StreetSuffix>St.</StreetSuffix>
<Unit>207</Unit>
<City>Denver</City>
<State>CO</State>
<Zip>80123</Zip>
<AddressLine1>123 S. Main St.</AddressLine1>
</Address>
Thanks,
John
Upvotes: 1
Views: 2879
Reputation: 6541
Your question is a bit confusing because you mention the XmlSerializer but you show a DataContract class. Is the data being deserialized (read) and serialized (written) with the same serializer? If so, is it the DataContractSerializer or the XmlSerializer? Or are you trying to read with the DataContractSerializer and write with the XmlSerializer? Anyway, assuming the simple case, that you both read and write using the DataContractSerializer, all you need to do is to make AddressLine1 into a property with a getter and setter and mark it with [DataMember(IsRequired=false)]. Then, in the AddressLine1 property getter, put your address concatenation code, and in the property setter just do nothing. This way, on deserialization, AddressLine1 will just be ignored (even if it's not present at all in the XML it won't cause an error), but on serialization it will be correctly written out.
Upvotes: 3
Reputation: 22906
I would have thought that you would not need to serialize the AddressLine1 property at all and simply have it as a helper read-only property.
[IgnoreDataMember()]
public string AddressLine1
{
get
{
return StreetNumber + " " + StreetDirection + " " + StreetName + " " + StreetSuffice;
}
}
As the value can be constructed whenever it is needed there is no point in serializing and transferring it in addition to the street set of properties. Of course, you could make the implemention more efficient by caching the value and only recreating it when one of the street properties actually changes.
Upvotes: 1