Deserializing an object from multiple files in C# - c#

Is it possible to deserialize a single object from multiple XML files? For example, if I have the following class:
[XmlInclude(typeof(SubClass))]
[XmlRoot]
public class BaseClass
{
[XmlElement]
public virtual int CommonSetting { get; set; }
}
[XmlRoot]
public class SubClass : BaseClass
{
[XmlElement]
public int OtherSetting { get; set; }
}
I want to deserialize an instance of 'SubClass' from XML, but I want to split the definition into two distinct files. For example:
BaseClass.xml
<BaseClass>
<CommonSetting>10</CommonSetting>
</BaseClass>
SubClass.xml
<SubClass>
<OtherSetting>5</OtherSetting>
</SubClass>
And secondly, is it then possible to override inherited 'common' settings by setting them inside the 'SubClass.xml' file. For example, if I defined 'SubClass.xml' as:
<SubClass>
<CommonSetting>5</CommonSetting>
<OtherSetting>5</OtherSetting>
</SubClass>
Then I would like to have an object 'Subclass' with a 'CommonSetting' of 5, rather than 10.
Is the above possible and if so, how can I go about it? Currently all I can achieve is to deserialise an instance of 'BaseClass' and 'SubClass' separately, and 'SubClass' has null/default values for settings derived from 'BaseClass'.

Related

XML Serialization Derived Types using value of an Attribute

I am modifying a set of classes that are being serialized, and I have a question that I cannot find the answer to. The old classes had a very large class called Control that is further classified by a ControlType attribute
enum ControlType
{
ControlType1 = 0,
ControlType2 = 1
}
public class Control
{
[XmlAttribute("a")]
public string a { get; set; }
[XmlAttribute("b")]
public string b { get; set; }
[XmlAttribute("Type")]
public ControlType Type {get; set;)
}
in the simplified sample above the original designer did not separate out the class into subclasses. what we really want is
class baseControl
{
[XmlAttribute("Type")]
public ControlType Type {get; set;}
}
class Control1 : baseControl
{
[XmlAttribute("a")]
public string a { get; set; }
}
class Control2 : baseControl
{
[XmlAttribute("b")]
public string b { get; set; }
}
we want to separate out the classes but we want the original xml to be compatible
in the old hierarchy all controls types (defined by ControlType) were serialized as
<Control Type="ControlType1" a="xxxx" />
<Control Type="ControlType2" b="xxxxx" />
if we use the new structures obviously the new structure would look like
<Control1 Type="ControlType1" a="xxxx" />
<Control2 Type="ControlType2" b="xxxxx" />
but we really want to serialize all of the new derived classes as "Control" and when we deserialize we want to change the allocated type to the derived type based on the value of an Attribute.
Is this possible?
The only chance to accomplish such behavior is to implemnent IXmlSerializable on the class corresponding to the surrounding element, and provide a custom (de)serialization behavior.
public class ControlContainer : IXmlSerializable
{
// a single / array of / list of BaseControls
public BaseControl Control { get; set; }
// … any other properties
// … implement IXmlSerializable here to have Control
// and any other properties (de)serialized
}

XML Serialize subclasses, to same xml name (without type name)

I have a base class (eg)
[XmlType("address")]
[XmlInclude(typeof(AddressUK))]
[XmlInclude(typeof(AddressEurope))]
public class AddressBase
{
// No serialized properties
}
and as you can see, I've decorated it to serialize to an element of 'address' and to expect some subclasses:
public class AddressUK : AddressBase
{
[XmlElement("company")]
[AddressField(AddressFieldType.Organisation, Required = true, MaxSize = 60)]
public string Company { get; set; }
}
public class AddressEurope : AddressBase
{
[XmlElement("company")]
[AddressField(AddressFieldType.Organisation, Required = true, MaxSize = 40)]
public string Company { get; set; }
}
The only reason I have these subclasses is so that I can decorate them with custom AddressField attributes. (Each subclass potentially has different settings, and the base class has methods that populates the address fields based on these attributes). Other than the AddressField attributes, these sub classes should serialize identically
But when I do serialize this my address node serializes as (eg)
...
<address p5:type="AddressUK" xmlns:p5="http://www.w3.org/2001/XMLSchema-instance">
<company>Company Name</company>
...
I'd really like it to just serialize as <address> without the type and namespace information. I suspect it's trying to help me there, as without that information I wouldn't be able to deserialize it correctly, but for my scenario (integration with 3rd party provider) that information is redundant and not expected by them (and I don't need to deserialize in such an awkward way)
Is this possible, or am I approaching this from entirely the wrong angle?

protobuf-net inheritance from child to parent

I have a parent class that I want to have many flat children. That means 10 or more different classes would inherent from one class.
Here is what I have.
Base Class:
[ProtoContract]
[ProtoInclude(500, typeof(Message1Send))]
[ProtoInclude(501, typeof(Message2Send))]
public class MessageBase
{
[ProtoMember(1)]
public string Topic {get;set;}
[ProtoMember(2)]
public string Action { get; set; }
}
2 of many Child Classes:
[ProtoContract]
public class Message1Send : MessageBase
{
[ProtoMember(1)]
public string Property1 { get; set; }
}
[ProtoContract]
public class Message2Send : MessageBase
{
[ProtoMember(1)]
public string Property1 { get; set; }
}
I want to be able to tell the child object I am part of a base class.
I don’t what to get to the point where my base class is as follows:
[ProtoContract]
[ProtoInclude(500, typeof(Message1Send))]
[ProtoInclude(501, typeof(Message2Send))]
[ProtoInclude(502, typeof(Message3Send))]
[ProtoInclude(503, typeof(Message4Send))]
[ProtoInclude(504, typeof(Message5Send))]
[ProtoInclude(505, typeof(Message6Send))]
[ProtoInclude(506, typeof(Message7Send))]
[ProtoInclude(507, typeof(Message8Send))]
[ProtoInclude(508, typeof(Message9Send))]
[ProtoInclude(509, typeof(Message10Send))]
public class MessageBase
{
[ProtoMember(1)]
public string Topic {get;set;}
[ProtoMember(2)]
public string Action { get; set; }
}
Is there a way I can have each one of the Send classes to just add one reference to the base class so I don’t have to keep adding ProtoInclude for every flat child I create?
The problem is one of reliability. Reflection makes veryfew repeatable / reliable guarantees, and it is very important that if you serialize data today, then edit your app to add two new types, each type still has the same number as it did oroginally. Even if you've added some new types, renamed some, and possibly removed two that you weren't really using.
The attribute guarantees this by making the field-number repeatable. The reason it is on the parent (not the child) is that it is much more reliable to walk up the type-chain than down it.
However: if you have a reliable repeatable way of generating field numbers for sub-types, you can use RuntimeTypeModel to configure the serializer to your liking.

storing a serializable object in the session

I have an object that I store in the session, something like this:
[Serializable]
public class GoyaAppUserServerSession
{
public int TheInt{ get; set; }
public string TheString{ get; set; }
public byte TheByte{ get; set; }
public void SomeMethod() { ... }
public void SomeOtherMethod() { ... }
}
My server session has 3 values and 2 methods. When the object is serialized and deserialized, does the serialization only apply to the values, in which case it's negligible, or is the code that's inside the methods also serialized as a string?
Thanks.
Only the values; since methods are a compiled definition of the class, there is no reason to store these; therefore it only stores the values of the properties. Depending on what you are serializing with, it usually uses the properties as the names of the fields during the serialization process. For instance, if you use XML, it would use the property name as attribute or element, and the value as the inner content.

Object serialization and derived classes; controlling xml output

I have 2 derived classes that will be serialized into xml.
While the code works fine (XmlSerializer, nothing strange), the serialization of DataScenario causes its MyData property items to produce Xmlelement names from the base class name:
<DataScenario>
<MyData>
<ScenarioData/>
<ScenarioData/>
<ScenarioData/>
</MyData>
<DataScenario>
Instead, i'm trying to have these items produce XmlElement names from their derived classes
<DataScenario>
<MyData>
<type1/>
<type1/>
<type2/>
</MyData>
<DataScenario>
Is this even possible? Keep in mind I need to deserialize as well; I'm unsure whether the Deserialize process will understand that derived objects need to be created.
Sample code i'm using is as follows.
[Serializable]
[XmlInclude(typeof(Type1))]
[XmlInclude(typeof(Type2))]
public class Scenario
{
[XmlElement("location")]
public string Location { get; set; }
[XmlElement("value")]
public string Value { get; set; }
public Scenario()
{
}
}
[Serializable]
[XmlType("type1")]
public class Type1 : Scenario
{
public FillPointData() : base() { }
}
[Serializable]
[XmlType("type2")]
public class Type2 : Scenario
{
public TestData() : base() { }
}
//Hosting class of all scenarios
public DataScenario()
{
public List<Scenario> MyData{ get; set; }
}
You can define what kind of Elements are in the Collection with the XmlArrayItem attribute.
If the Type is known (defined as you did with the XmlInclude attribute) it will create Tags "Type1", "Type2". If the Types are not known, it will still create a Tag called ScenarioData with an Attribute xsi:type="Type1" which is used to map the type while deserialization.
[XmlArrayItem(typeof(Type1))]
[XmlArrayItem(typeof(Type2))]
Public List<Scenario> Children
{
// getter & setter
}

Categories

Resources