XML Serialization error - Invalid or missing value of the choice identifier 'ItemsElementName' of type 'ItemsChoiceType[]'
Clash 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!
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.
Your question doesn't include the definition and construction of
tradeAreas
, so it doesn't compile. But if I comment out the initialization ofItems
andItemsElementName
then your code works and successfully serializes yourmri
class to XML, see dotnetfiddle.net/Sep6IP. Can you provide a Minimal, Complete, and Verifiable example please?– dbc
Aug 10 at 9:55