XML Serialization error - Invalid or missing value of the choice identifier 'ItemsElementName' of type 'ItemsChoiceType[]'

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



XML Serialization error - Invalid or missing value of the choice identifier 'ItemsElementName' of type 'ItemsChoiceType'



I am trying to serialize an object to be passed to a web service and getting the error above. I can see when debugging that the value is present in the object itself but it doesn't seem to be picking this up:


string tradeAreas = new string "Area1", "Area2", "Area3", "Area4";
//RetrieveMarketResultsFor
ItemsChoiceType choices = new ItemsChoiceType ItemsChoiceType.area ;
MarketResultIdentifier mri = new MarketResultIdentifier

ItemsElementName = choices,
Items = tradeAreas,
ItemElementName = ItemChoiceType6.applyingDate,
Item = DateTime.Today.AddDays(-1)
;

var ser = new XmlSerializer(typeof(MarketResultIdentifier));
using (var stream = new FileStream("mri.xml", FileMode.Create))
ser.Serialize(stream, mri);



The web service generated code has the following classes used in the above code:


[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.3130.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:openaccess")]
public partial class MarketResultIdentifier : OpenAccessAbstractObject

private string itemsField;

private ItemsChoiceType itemsElementNameField;

private object itemField;

private ItemChoiceType6 itemElementNameField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("area", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("areaNames", typeof(string))]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
public string Items
get
return this.itemsField;

set
this.itemsField = value;



/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("ItemsElementName")]
[System.Xml.Serialization.XmlIgnoreAttribute()]
public ItemsChoiceType ItemsElementName
get
return this.itemsElementNameField;

set
this.itemsElementNameField = value;



/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("applyingDate", typeof(System.DateTime), DataType="date")]
[System.Xml.Serialization.XmlElementAttribute("auctionIdentification", typeof(AuctionIdentification))]
[System.Xml.Serialization.XmlElementAttribute("deliveryDay", typeof(System.DateTime), DataType="date")]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")]
public object Item
get
return this.itemField;

set
this.itemField = value;



/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public ItemChoiceType6 ItemElementName
get
return this.itemElementNameField;

set
this.itemElementNameField = value;




/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.3130.0")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:openaccess", IncludeInSchema=false)]
public enum ItemsChoiceType

/// <remarks/>
area,

/// <remarks/>
areaNames,


[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.3130.0")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:openaccess", IncludeInSchema=false)]
public enum ItemChoiceType6

/// <remarks/>
applyingDate,

/// <remarks/>
auctionIdentification,

/// <remarks/>
deliveryDay,



It fails at line when trying ser.serialize....



Any help appreciated :)



Solution
Turns out this was just down to me being stupid! Thanks to @dbc for pointing this out. My tradeAreas array had 4 items in there (i was using the wrong array here) which it should have only had one!





Your question doesn't include the definition and construction of tradeAreas, so it doesn't compile. But if I comment out the initialization of Items and ItemsElementName then your code works and successfully serializes your mri class to XML, see dotnetfiddle.net/Sep6IP. Can you provide a Minimal, Complete, and Verifiable example please?
– dbc
Aug 10 at 9:55



tradeAreas


Items


ItemsElementName


mri





Also can't reproduce if I set up tradeAreas as an array of strings with one entry, see dotnetfiddle.net/rMTbwh. Are you sure your choices and tradeAreas arrays have the same number of items?
– dbc
Aug 10 at 10:24


tradeAreas


choices


tradeAreas





HI @dbc looks like that was it! my tradeAreas array had 4 items in there, when i remove the others and have just one area it is serializing as expected. Thanks for pointing this out!
– Gavin Crawley
Aug 10 at 10:36





The meta question Is it OK for users to edit the accepted answer into their question? suggests not editing the answer into the question. You might want to take the solution out and add it as an answer, or accept one of the answers, instead.
– dbc
Aug 10 at 12:06





2 Answers
2



When you use XmlChoiceIdentifierAttribute to deserialize a sequence of choice elements into some shared data type (here, string), you need to add two arrays to your data model:


XmlChoiceIdentifierAttribute


string



A property returning an array of objects of appropriate type to capture the choice element contents, here the four string values in the tradeAreas array.


tradeAreas



This first array must be marked with [XmlChoiceIdentifier(name)] where name is the name of the second array, as well as [XmlElement(elementName)] attributes for each possible choice element name.


[XmlChoiceIdentifier(name)]


name


[XmlElement(elementName)]



And a property returning an array of enums to capture the choice element names, here <area> for each element.


<area>



This array must be marked with [XmlIgnore].


[XmlIgnore]



And finally, since the second array captures the element names for the element contents in the first array, the arrays must be in 1-1 correspondence. Thus choices must be initialized to the same length as tradeAreas, e.g. as follows:


choices


tradeAreas


var tradeAreas = new string "Area1", "Area2", "Area3", "Area4";
var choices = Enumerable.Repeat(ItemsChoiceType.area, tradeAreas.Length).ToArray();



In your sample code tradeAreas has four entries while choices has but one, leading to the exception you see.


tradeAreas


choices



Working sample .Net fiddle here.



For documentation on binding to XML choice elements using XmlSerializer, see Choice Element Binding Support: Differentiating by Name as well as XmlChoiceIdentifierAttribute Class: Remarks. For a simple manual example, see e.g. this answer to How to Serialize List<T> property in c# without showing its type in XML serialization.


XmlSerializer





Thanks again for your help with this! much appreciated :)
– Gavin Crawley
Aug 10 at 12:09



You posted code works provided you add following :


string tradeAreas = null;

public class AuctionIdentification


public class OpenAccessAbstractObject







By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard