Deserialize class properties to derived class instead of base abstract class










0















The structure here is a bit convoluted so please bear with me. I hope that there's a way to do what a want to do, but if it's not possible then feel free to tell me!



Unfortunately I've not been involved in the design process of the XML file spec from the beginning, the goalposts have been moved a dozen times and the spec can't be amended for the sake of making it easier for me to do as any spec amendments are extortionately priced (yes, even renaming XML elements!)



Anyway I digress.



There are two different types of purchase order that have a slightly different file structure and slightly different processing logic and I am trying to handle them both with the same code instead of having two different projects for what is nearly identical.



Both types of purchase order derive from a set of abstract classes that determine basic business logic that both PO types share (quantity, cost, PO number, etc.).



Base classes



abstract class PO 
[XmlIgnore]
abstract POType PurchaseOrderType get;
[XmlIgnore]
abstract PO_Head Header get;set;
[XmlIgnore]
abstract List<PO_Line> LineItems get;set;


abstract class PO_Head
[XmlIgnore]
abstract string PONumber get;set;


abstract class PO_Line
[XmlIgnore]
abstract string ItemCode get;set;
[XmlIgnore]
abstract decimal UnitCost get;set;
[XmlIgnore]
abstract int OrderQty get;set;



Derived classes



class POR : PO 
// POR implementations


class POR_Head : PO_Line
// POR implementations


class POR_Line : PO_Line
// POR implementations


class CPO : PO
// CPO implementations


class CPO_Head : PO_Line
// CPO implementations


class CPO_Line : PO_Line
// CPO implementations



The base abstract class is then used in the code to process each purchase order and import them into our accounting system.



for (int i = pending.Transactions.Count -1; i > -1; i--) 
PO pendingOrder = (PO)pending.Transactions[i];
// Import PO type



The problem is that when I attempt to deserialize into each derived class as appropriate, it attempts to deserialize the Header and LineItems into the derived types PO_Head and PO_Line. Is there any way I can explicitly tell the XmlSerializer to treat Header and LineItems as the derived class versions - CPO_Head and CPO_Line or POR_Head and POR_Line - depending on the class that is being serialized - CPO or POR respectively. Something akin to the below.



class CPO : PO 
[XmlIgnore]
override POType PurchaseOrderType => POType.CPO;

[XmlElement("CPO_Head")]
[XmlDeserializerType(typeof(CPO_Head))]
override PO_Head Header get;set;

[XmlArray("CPO_Lines")]
[XmlArrayItem("CPO_Line")]
[XmlDeserializerType(typeof(CPO_Line))]
override List<PO_Line> LineItems get;set;



Kind of dug myself a hole with this one (first time using deserialization) so I'm hoping there's an easy way out that would save me having to rewrite a ton of the work I've done!



TIA



EDIT - code used to deserialize/serialize as requested



public static void SerializeToXmlFile(object obj, FileInfo dstFile)

XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
using (FileStream fs = dstFile.Open(FileMode.Create, FileAccess.Write))

xmlSerializer.Serialize(fs, obj);




public static object DeserializeFromXmlFile(FileInfo srcFile, Type type)

XmlSerializer xmlSerializer = new XmlSerializer(type);
using (FileStream fs = srcFile.Open(FileMode.Open, FileAccess.Read))

return xmlSerializer.Deserialize(fs);



public static void Main(string args)

// Deserialize from XML file
FileInfo srcFile = new FileInfo("pathtofile");
Type t;
if (srcFile.Name.Substring(0,3) == "CPO")
t = typeof(CPO);
else if (srcFile.Name.Substring(0,3) == "POR")
t = typeof(POR);

PO po = DeserializeFromXmlFile(file, t);

// Process the file
// ...

// Serialize back to file
FileInfo dstFile = new FileInfo("newpathtofile");
SerializeToXmlFile(po, dstFile);



EDIT - fixed



As per the marked correct answer I was able to resolve this by specifying the Type in the XmlElement and XmlArrayItem attributes.



class POR 
[XmlElement(typeof(POR_Head), ElementName="PO_Head")]
override PO_Head Header get;set; = new POR_Head();
[XmlArray("PO_Lines")]
[XmlArrayItem(typeof(POR_Line), ElementName="PO_Line")]
override List<PO_Line> LineItems get;set; = new List<LineItems>();


class CPO
[XmlElement(typeof(CPO_Head), ElementName="PO_Head")]
override PO_Head Header get;set; = new CPO_Head();
[XmlArray("PO_Lines")]
[XmlArrayItem(typeof(CPO_Line), ElementName="PO_Line")]
override List<PO_Line> LineItems get;set; = new List<LineItems>();










share|improve this question
























  • When working with weakly typed stuff (inlcuding unstable structured XML), there is the ExpandoObject class. Deserialize the XML into a ExpandoObject. Then later decide wich proper .NET class you translate it too, based on the values in the EO. That allows you to seperate the deserialization of the data and hte picking of the proper (sub) class.

    – Christopher
    Nov 12 '18 at 17:10











  • Can you edit your post to include the code that you are using to serialize and deserialize the objects?

    – John Wu
    Nov 12 '18 at 17:35











  • @JohnWu I have added that code as requested.

    – ryansin
    Nov 13 '18 at 8:23











  • @Christopher can you add an example of ExpandoObject please?

    – ryansin
    Nov 13 '18 at 8:37















0















The structure here is a bit convoluted so please bear with me. I hope that there's a way to do what a want to do, but if it's not possible then feel free to tell me!



Unfortunately I've not been involved in the design process of the XML file spec from the beginning, the goalposts have been moved a dozen times and the spec can't be amended for the sake of making it easier for me to do as any spec amendments are extortionately priced (yes, even renaming XML elements!)



Anyway I digress.



There are two different types of purchase order that have a slightly different file structure and slightly different processing logic and I am trying to handle them both with the same code instead of having two different projects for what is nearly identical.



Both types of purchase order derive from a set of abstract classes that determine basic business logic that both PO types share (quantity, cost, PO number, etc.).



Base classes



abstract class PO 
[XmlIgnore]
abstract POType PurchaseOrderType get;
[XmlIgnore]
abstract PO_Head Header get;set;
[XmlIgnore]
abstract List<PO_Line> LineItems get;set;


abstract class PO_Head
[XmlIgnore]
abstract string PONumber get;set;


abstract class PO_Line
[XmlIgnore]
abstract string ItemCode get;set;
[XmlIgnore]
abstract decimal UnitCost get;set;
[XmlIgnore]
abstract int OrderQty get;set;



Derived classes



class POR : PO 
// POR implementations


class POR_Head : PO_Line
// POR implementations


class POR_Line : PO_Line
// POR implementations


class CPO : PO
// CPO implementations


class CPO_Head : PO_Line
// CPO implementations


class CPO_Line : PO_Line
// CPO implementations



The base abstract class is then used in the code to process each purchase order and import them into our accounting system.



for (int i = pending.Transactions.Count -1; i > -1; i--) 
PO pendingOrder = (PO)pending.Transactions[i];
// Import PO type



The problem is that when I attempt to deserialize into each derived class as appropriate, it attempts to deserialize the Header and LineItems into the derived types PO_Head and PO_Line. Is there any way I can explicitly tell the XmlSerializer to treat Header and LineItems as the derived class versions - CPO_Head and CPO_Line or POR_Head and POR_Line - depending on the class that is being serialized - CPO or POR respectively. Something akin to the below.



class CPO : PO 
[XmlIgnore]
override POType PurchaseOrderType => POType.CPO;

[XmlElement("CPO_Head")]
[XmlDeserializerType(typeof(CPO_Head))]
override PO_Head Header get;set;

[XmlArray("CPO_Lines")]
[XmlArrayItem("CPO_Line")]
[XmlDeserializerType(typeof(CPO_Line))]
override List<PO_Line> LineItems get;set;



Kind of dug myself a hole with this one (first time using deserialization) so I'm hoping there's an easy way out that would save me having to rewrite a ton of the work I've done!



TIA



EDIT - code used to deserialize/serialize as requested



public static void SerializeToXmlFile(object obj, FileInfo dstFile)

XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
using (FileStream fs = dstFile.Open(FileMode.Create, FileAccess.Write))

xmlSerializer.Serialize(fs, obj);




public static object DeserializeFromXmlFile(FileInfo srcFile, Type type)

XmlSerializer xmlSerializer = new XmlSerializer(type);
using (FileStream fs = srcFile.Open(FileMode.Open, FileAccess.Read))

return xmlSerializer.Deserialize(fs);



public static void Main(string args)

// Deserialize from XML file
FileInfo srcFile = new FileInfo("pathtofile");
Type t;
if (srcFile.Name.Substring(0,3) == "CPO")
t = typeof(CPO);
else if (srcFile.Name.Substring(0,3) == "POR")
t = typeof(POR);

PO po = DeserializeFromXmlFile(file, t);

// Process the file
// ...

// Serialize back to file
FileInfo dstFile = new FileInfo("newpathtofile");
SerializeToXmlFile(po, dstFile);



EDIT - fixed



As per the marked correct answer I was able to resolve this by specifying the Type in the XmlElement and XmlArrayItem attributes.



class POR 
[XmlElement(typeof(POR_Head), ElementName="PO_Head")]
override PO_Head Header get;set; = new POR_Head();
[XmlArray("PO_Lines")]
[XmlArrayItem(typeof(POR_Line), ElementName="PO_Line")]
override List<PO_Line> LineItems get;set; = new List<LineItems>();


class CPO
[XmlElement(typeof(CPO_Head), ElementName="PO_Head")]
override PO_Head Header get;set; = new CPO_Head();
[XmlArray("PO_Lines")]
[XmlArrayItem(typeof(CPO_Line), ElementName="PO_Line")]
override List<PO_Line> LineItems get;set; = new List<LineItems>();










share|improve this question
























  • When working with weakly typed stuff (inlcuding unstable structured XML), there is the ExpandoObject class. Deserialize the XML into a ExpandoObject. Then later decide wich proper .NET class you translate it too, based on the values in the EO. That allows you to seperate the deserialization of the data and hte picking of the proper (sub) class.

    – Christopher
    Nov 12 '18 at 17:10











  • Can you edit your post to include the code that you are using to serialize and deserialize the objects?

    – John Wu
    Nov 12 '18 at 17:35











  • @JohnWu I have added that code as requested.

    – ryansin
    Nov 13 '18 at 8:23











  • @Christopher can you add an example of ExpandoObject please?

    – ryansin
    Nov 13 '18 at 8:37













0












0








0








The structure here is a bit convoluted so please bear with me. I hope that there's a way to do what a want to do, but if it's not possible then feel free to tell me!



Unfortunately I've not been involved in the design process of the XML file spec from the beginning, the goalposts have been moved a dozen times and the spec can't be amended for the sake of making it easier for me to do as any spec amendments are extortionately priced (yes, even renaming XML elements!)



Anyway I digress.



There are two different types of purchase order that have a slightly different file structure and slightly different processing logic and I am trying to handle them both with the same code instead of having two different projects for what is nearly identical.



Both types of purchase order derive from a set of abstract classes that determine basic business logic that both PO types share (quantity, cost, PO number, etc.).



Base classes



abstract class PO 
[XmlIgnore]
abstract POType PurchaseOrderType get;
[XmlIgnore]
abstract PO_Head Header get;set;
[XmlIgnore]
abstract List<PO_Line> LineItems get;set;


abstract class PO_Head
[XmlIgnore]
abstract string PONumber get;set;


abstract class PO_Line
[XmlIgnore]
abstract string ItemCode get;set;
[XmlIgnore]
abstract decimal UnitCost get;set;
[XmlIgnore]
abstract int OrderQty get;set;



Derived classes



class POR : PO 
// POR implementations


class POR_Head : PO_Line
// POR implementations


class POR_Line : PO_Line
// POR implementations


class CPO : PO
// CPO implementations


class CPO_Head : PO_Line
// CPO implementations


class CPO_Line : PO_Line
// CPO implementations



The base abstract class is then used in the code to process each purchase order and import them into our accounting system.



for (int i = pending.Transactions.Count -1; i > -1; i--) 
PO pendingOrder = (PO)pending.Transactions[i];
// Import PO type



The problem is that when I attempt to deserialize into each derived class as appropriate, it attempts to deserialize the Header and LineItems into the derived types PO_Head and PO_Line. Is there any way I can explicitly tell the XmlSerializer to treat Header and LineItems as the derived class versions - CPO_Head and CPO_Line or POR_Head and POR_Line - depending on the class that is being serialized - CPO or POR respectively. Something akin to the below.



class CPO : PO 
[XmlIgnore]
override POType PurchaseOrderType => POType.CPO;

[XmlElement("CPO_Head")]
[XmlDeserializerType(typeof(CPO_Head))]
override PO_Head Header get;set;

[XmlArray("CPO_Lines")]
[XmlArrayItem("CPO_Line")]
[XmlDeserializerType(typeof(CPO_Line))]
override List<PO_Line> LineItems get;set;



Kind of dug myself a hole with this one (first time using deserialization) so I'm hoping there's an easy way out that would save me having to rewrite a ton of the work I've done!



TIA



EDIT - code used to deserialize/serialize as requested



public static void SerializeToXmlFile(object obj, FileInfo dstFile)

XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
using (FileStream fs = dstFile.Open(FileMode.Create, FileAccess.Write))

xmlSerializer.Serialize(fs, obj);




public static object DeserializeFromXmlFile(FileInfo srcFile, Type type)

XmlSerializer xmlSerializer = new XmlSerializer(type);
using (FileStream fs = srcFile.Open(FileMode.Open, FileAccess.Read))

return xmlSerializer.Deserialize(fs);



public static void Main(string args)

// Deserialize from XML file
FileInfo srcFile = new FileInfo("pathtofile");
Type t;
if (srcFile.Name.Substring(0,3) == "CPO")
t = typeof(CPO);
else if (srcFile.Name.Substring(0,3) == "POR")
t = typeof(POR);

PO po = DeserializeFromXmlFile(file, t);

// Process the file
// ...

// Serialize back to file
FileInfo dstFile = new FileInfo("newpathtofile");
SerializeToXmlFile(po, dstFile);



EDIT - fixed



As per the marked correct answer I was able to resolve this by specifying the Type in the XmlElement and XmlArrayItem attributes.



class POR 
[XmlElement(typeof(POR_Head), ElementName="PO_Head")]
override PO_Head Header get;set; = new POR_Head();
[XmlArray("PO_Lines")]
[XmlArrayItem(typeof(POR_Line), ElementName="PO_Line")]
override List<PO_Line> LineItems get;set; = new List<LineItems>();


class CPO
[XmlElement(typeof(CPO_Head), ElementName="PO_Head")]
override PO_Head Header get;set; = new CPO_Head();
[XmlArray("PO_Lines")]
[XmlArrayItem(typeof(CPO_Line), ElementName="PO_Line")]
override List<PO_Line> LineItems get;set; = new List<LineItems>();










share|improve this question
















The structure here is a bit convoluted so please bear with me. I hope that there's a way to do what a want to do, but if it's not possible then feel free to tell me!



Unfortunately I've not been involved in the design process of the XML file spec from the beginning, the goalposts have been moved a dozen times and the spec can't be amended for the sake of making it easier for me to do as any spec amendments are extortionately priced (yes, even renaming XML elements!)



Anyway I digress.



There are two different types of purchase order that have a slightly different file structure and slightly different processing logic and I am trying to handle them both with the same code instead of having two different projects for what is nearly identical.



Both types of purchase order derive from a set of abstract classes that determine basic business logic that both PO types share (quantity, cost, PO number, etc.).



Base classes



abstract class PO 
[XmlIgnore]
abstract POType PurchaseOrderType get;
[XmlIgnore]
abstract PO_Head Header get;set;
[XmlIgnore]
abstract List<PO_Line> LineItems get;set;


abstract class PO_Head
[XmlIgnore]
abstract string PONumber get;set;


abstract class PO_Line
[XmlIgnore]
abstract string ItemCode get;set;
[XmlIgnore]
abstract decimal UnitCost get;set;
[XmlIgnore]
abstract int OrderQty get;set;



Derived classes



class POR : PO 
// POR implementations


class POR_Head : PO_Line
// POR implementations


class POR_Line : PO_Line
// POR implementations


class CPO : PO
// CPO implementations


class CPO_Head : PO_Line
// CPO implementations


class CPO_Line : PO_Line
// CPO implementations



The base abstract class is then used in the code to process each purchase order and import them into our accounting system.



for (int i = pending.Transactions.Count -1; i > -1; i--) 
PO pendingOrder = (PO)pending.Transactions[i];
// Import PO type



The problem is that when I attempt to deserialize into each derived class as appropriate, it attempts to deserialize the Header and LineItems into the derived types PO_Head and PO_Line. Is there any way I can explicitly tell the XmlSerializer to treat Header and LineItems as the derived class versions - CPO_Head and CPO_Line or POR_Head and POR_Line - depending on the class that is being serialized - CPO or POR respectively. Something akin to the below.



class CPO : PO 
[XmlIgnore]
override POType PurchaseOrderType => POType.CPO;

[XmlElement("CPO_Head")]
[XmlDeserializerType(typeof(CPO_Head))]
override PO_Head Header get;set;

[XmlArray("CPO_Lines")]
[XmlArrayItem("CPO_Line")]
[XmlDeserializerType(typeof(CPO_Line))]
override List<PO_Line> LineItems get;set;



Kind of dug myself a hole with this one (first time using deserialization) so I'm hoping there's an easy way out that would save me having to rewrite a ton of the work I've done!



TIA



EDIT - code used to deserialize/serialize as requested



public static void SerializeToXmlFile(object obj, FileInfo dstFile)

XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
using (FileStream fs = dstFile.Open(FileMode.Create, FileAccess.Write))

xmlSerializer.Serialize(fs, obj);




public static object DeserializeFromXmlFile(FileInfo srcFile, Type type)

XmlSerializer xmlSerializer = new XmlSerializer(type);
using (FileStream fs = srcFile.Open(FileMode.Open, FileAccess.Read))

return xmlSerializer.Deserialize(fs);



public static void Main(string args)

// Deserialize from XML file
FileInfo srcFile = new FileInfo("pathtofile");
Type t;
if (srcFile.Name.Substring(0,3) == "CPO")
t = typeof(CPO);
else if (srcFile.Name.Substring(0,3) == "POR")
t = typeof(POR);

PO po = DeserializeFromXmlFile(file, t);

// Process the file
// ...

// Serialize back to file
FileInfo dstFile = new FileInfo("newpathtofile");
SerializeToXmlFile(po, dstFile);



EDIT - fixed



As per the marked correct answer I was able to resolve this by specifying the Type in the XmlElement and XmlArrayItem attributes.



class POR 
[XmlElement(typeof(POR_Head), ElementName="PO_Head")]
override PO_Head Header get;set; = new POR_Head();
[XmlArray("PO_Lines")]
[XmlArrayItem(typeof(POR_Line), ElementName="PO_Line")]
override List<PO_Line> LineItems get;set; = new List<LineItems>();


class CPO
[XmlElement(typeof(CPO_Head), ElementName="PO_Head")]
override PO_Head Header get;set; = new CPO_Head();
[XmlArray("PO_Lines")]
[XmlArrayItem(typeof(CPO_Line), ElementName="PO_Line")]
override List<PO_Line> LineItems get;set; = new List<LineItems>();







c# xml-deserialization






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 9:14







ryansin

















asked Nov 12 '18 at 17:05









ryansinryansin

724725




724725












  • When working with weakly typed stuff (inlcuding unstable structured XML), there is the ExpandoObject class. Deserialize the XML into a ExpandoObject. Then later decide wich proper .NET class you translate it too, based on the values in the EO. That allows you to seperate the deserialization of the data and hte picking of the proper (sub) class.

    – Christopher
    Nov 12 '18 at 17:10











  • Can you edit your post to include the code that you are using to serialize and deserialize the objects?

    – John Wu
    Nov 12 '18 at 17:35











  • @JohnWu I have added that code as requested.

    – ryansin
    Nov 13 '18 at 8:23











  • @Christopher can you add an example of ExpandoObject please?

    – ryansin
    Nov 13 '18 at 8:37

















  • When working with weakly typed stuff (inlcuding unstable structured XML), there is the ExpandoObject class. Deserialize the XML into a ExpandoObject. Then later decide wich proper .NET class you translate it too, based on the values in the EO. That allows you to seperate the deserialization of the data and hte picking of the proper (sub) class.

    – Christopher
    Nov 12 '18 at 17:10











  • Can you edit your post to include the code that you are using to serialize and deserialize the objects?

    – John Wu
    Nov 12 '18 at 17:35











  • @JohnWu I have added that code as requested.

    – ryansin
    Nov 13 '18 at 8:23











  • @Christopher can you add an example of ExpandoObject please?

    – ryansin
    Nov 13 '18 at 8:37
















When working with weakly typed stuff (inlcuding unstable structured XML), there is the ExpandoObject class. Deserialize the XML into a ExpandoObject. Then later decide wich proper .NET class you translate it too, based on the values in the EO. That allows you to seperate the deserialization of the data and hte picking of the proper (sub) class.

– Christopher
Nov 12 '18 at 17:10





When working with weakly typed stuff (inlcuding unstable structured XML), there is the ExpandoObject class. Deserialize the XML into a ExpandoObject. Then later decide wich proper .NET class you translate it too, based on the values in the EO. That allows you to seperate the deserialization of the data and hte picking of the proper (sub) class.

– Christopher
Nov 12 '18 at 17:10













Can you edit your post to include the code that you are using to serialize and deserialize the objects?

– John Wu
Nov 12 '18 at 17:35





Can you edit your post to include the code that you are using to serialize and deserialize the objects?

– John Wu
Nov 12 '18 at 17:35













@JohnWu I have added that code as requested.

– ryansin
Nov 13 '18 at 8:23





@JohnWu I have added that code as requested.

– ryansin
Nov 13 '18 at 8:23













@Christopher can you add an example of ExpandoObject please?

– ryansin
Nov 13 '18 at 8:37





@Christopher can you add an example of ExpandoObject please?

– ryansin
Nov 13 '18 at 8:37












1 Answer
1






active

oldest

votes


















1














I think you are looking for the XmlArrayItemAttribute. According to the docs:




You can apply the XmlArrayItemAttribute to any public read/write member that returns an array, or provides access to one. For example, a field that returns an array of objects, a collection, an ArrayList, or any class that implements the IEnumerable interface.



The XmlArrayItemAttribute supports polymorphism--in other words, it allows the XmlSerializer to add derived objects to an array.




If I understand the example correctly, the attribute should be written with a list of the possible derived types that are allowed in the serialized enumerable, e.g.



[XmlArrayItem (typeof(PO_Line), ElementName = "PO_Line"),
XmlArrayItem (typeof(CPO_Line),ElementName = "CPO_Line")]


Since you are only passing a string, the attribute interprets that as the ElementName, not the type. The type must be passed using typeof(ClassName).






share|improve this answer























  • Specifying the type in the XmlArrayItemAttribute and XmlElementAttribute is what fixed my issue, I will update my answer to show exactly what steps I took. Thanks so much!

    – ryansin
    Nov 13 '18 at 9:10











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53266907%2fdeserialize-class-properties-to-derived-class-instead-of-base-abstract-class%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














I think you are looking for the XmlArrayItemAttribute. According to the docs:




You can apply the XmlArrayItemAttribute to any public read/write member that returns an array, or provides access to one. For example, a field that returns an array of objects, a collection, an ArrayList, or any class that implements the IEnumerable interface.



The XmlArrayItemAttribute supports polymorphism--in other words, it allows the XmlSerializer to add derived objects to an array.




If I understand the example correctly, the attribute should be written with a list of the possible derived types that are allowed in the serialized enumerable, e.g.



[XmlArrayItem (typeof(PO_Line), ElementName = "PO_Line"),
XmlArrayItem (typeof(CPO_Line),ElementName = "CPO_Line")]


Since you are only passing a string, the attribute interprets that as the ElementName, not the type. The type must be passed using typeof(ClassName).






share|improve this answer























  • Specifying the type in the XmlArrayItemAttribute and XmlElementAttribute is what fixed my issue, I will update my answer to show exactly what steps I took. Thanks so much!

    – ryansin
    Nov 13 '18 at 9:10
















1














I think you are looking for the XmlArrayItemAttribute. According to the docs:




You can apply the XmlArrayItemAttribute to any public read/write member that returns an array, or provides access to one. For example, a field that returns an array of objects, a collection, an ArrayList, or any class that implements the IEnumerable interface.



The XmlArrayItemAttribute supports polymorphism--in other words, it allows the XmlSerializer to add derived objects to an array.




If I understand the example correctly, the attribute should be written with a list of the possible derived types that are allowed in the serialized enumerable, e.g.



[XmlArrayItem (typeof(PO_Line), ElementName = "PO_Line"),
XmlArrayItem (typeof(CPO_Line),ElementName = "CPO_Line")]


Since you are only passing a string, the attribute interprets that as the ElementName, not the type. The type must be passed using typeof(ClassName).






share|improve this answer























  • Specifying the type in the XmlArrayItemAttribute and XmlElementAttribute is what fixed my issue, I will update my answer to show exactly what steps I took. Thanks so much!

    – ryansin
    Nov 13 '18 at 9:10














1












1








1







I think you are looking for the XmlArrayItemAttribute. According to the docs:




You can apply the XmlArrayItemAttribute to any public read/write member that returns an array, or provides access to one. For example, a field that returns an array of objects, a collection, an ArrayList, or any class that implements the IEnumerable interface.



The XmlArrayItemAttribute supports polymorphism--in other words, it allows the XmlSerializer to add derived objects to an array.




If I understand the example correctly, the attribute should be written with a list of the possible derived types that are allowed in the serialized enumerable, e.g.



[XmlArrayItem (typeof(PO_Line), ElementName = "PO_Line"),
XmlArrayItem (typeof(CPO_Line),ElementName = "CPO_Line")]


Since you are only passing a string, the attribute interprets that as the ElementName, not the type. The type must be passed using typeof(ClassName).






share|improve this answer













I think you are looking for the XmlArrayItemAttribute. According to the docs:




You can apply the XmlArrayItemAttribute to any public read/write member that returns an array, or provides access to one. For example, a field that returns an array of objects, a collection, an ArrayList, or any class that implements the IEnumerable interface.



The XmlArrayItemAttribute supports polymorphism--in other words, it allows the XmlSerializer to add derived objects to an array.




If I understand the example correctly, the attribute should be written with a list of the possible derived types that are allowed in the serialized enumerable, e.g.



[XmlArrayItem (typeof(PO_Line), ElementName = "PO_Line"),
XmlArrayItem (typeof(CPO_Line),ElementName = "CPO_Line")]


Since you are only passing a string, the attribute interprets that as the ElementName, not the type. The type must be passed using typeof(ClassName).







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 13 '18 at 8:50









John WuJohn Wu

29.9k42752




29.9k42752












  • Specifying the type in the XmlArrayItemAttribute and XmlElementAttribute is what fixed my issue, I will update my answer to show exactly what steps I took. Thanks so much!

    – ryansin
    Nov 13 '18 at 9:10


















  • Specifying the type in the XmlArrayItemAttribute and XmlElementAttribute is what fixed my issue, I will update my answer to show exactly what steps I took. Thanks so much!

    – ryansin
    Nov 13 '18 at 9:10

















Specifying the type in the XmlArrayItemAttribute and XmlElementAttribute is what fixed my issue, I will update my answer to show exactly what steps I took. Thanks so much!

– ryansin
Nov 13 '18 at 9:10






Specifying the type in the XmlArrayItemAttribute and XmlElementAttribute is what fixed my issue, I will update my answer to show exactly what steps I took. Thanks so much!

– ryansin
Nov 13 '18 at 9:10


















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53266907%2fdeserialize-class-properties-to-derived-class-instead-of-base-abstract-class%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

Syphilis

Darth Vader #20