I trying to add extension method for Flurl that parse http response from xml to object. There is code
public static async Task<T> ReceiveXml<T>(this Task<IFlurlResponse> content)
{
var response = await content.ConfigureAwait(false);
if (response == null) return default(T);
try
{
var originData = await response.GetStreamAsync().ConfigureAwait(false);
var serializer = new XmlSerializer(typeof(T));
var result = (T)serializer.Deserialize(originData);
return result;
}
catch (Exception)
{
response.Dispose();
throw;
}
}
But when I trying to parse this xml
<Service.ABC
xmlns="http://schemas.datacontract.org/2004/07/Services.Public"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Amount>0</Amount>
<CustomerID i:nil="true"/>
<ID>0</ID>
<UpdatedDate i:nil="true"/>
</Service.ABC>
I got the an error
System.InvalidOperationException: <Service.ABC xmlns='http://schemas.datacontract.org/2004/07/Services.Public'> was not expected.
the model I build is from
[XmlRoot(ElementName="CustomerID")]
public class CustomerID {
[XmlAttribute(AttributeName="nil")]
public bool Nil { get; set; }
}
[XmlRoot(ElementName="UpdatedDate")]
public class UpdatedDate {
[XmlAttribute(AttributeName="nil")]
public bool Nil { get; set; }
}
[XmlRoot(ElementName="Service.ABC")]
public class ServiceABC {
[XmlElement(ElementName="Amount")]
public int Amount { get; set; }
[XmlElement(ElementName="CustomerID")]
public CustomerID CustomerID { get; set; }
[XmlElement(ElementName="ID")]
public int ID { get; set; }
[XmlElement(ElementName="UpdatedDate")]
public UpdatedDate UpdatedDate { get; set; }
[XmlAttribute(AttributeName="xmlns")]
public string Xmlns { get; set; }
[XmlAttribute(AttributeName="i")]
public string I { get; set; }
[XmlText]
public int Text { get; set; }
}
If use XmlDocument and load this xml file could be parse successfully, So... I think the file is correct. But What's the problem in XmlSerializer?
CodePudding user response:
The site you used doesn't seem reliable. Did you notice it gave you 3 XmlRoot
classes?
Using the Paste XML as classes feature in Visual Studio this is what I get:
// NOTE: Generated code may require at least .NET Framework 4.5 or .NET Core/Standard 2.0.
/// <remarks/>
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.datacontract.org/2004/07/Services.Public")]
[System.Xml.Serialization.XmlRootAttribute("Service.ABC", Namespace = "http://schemas.datacontract.org/2004/07/Services.Public", IsNullable = false)]
public partial class ServiceABC
{
private byte amountField;
private object customerIDField;
private byte idField;
private object updatedDateField;
/// <remarks/>
public byte Amount
{
get
{
return this.amountField;
}
set
{
this.amountField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable = true)]
public object CustomerID
{
get
{
return this.customerIDField;
}
set
{
this.customerIDField = value;
}
}
/// <remarks/>
public byte ID
{
get
{
return this.idField;
}
set
{
this.idField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable = true)]
public object UpdatedDate
{
get
{
return this.updatedDateField;
}
set
{
this.updatedDateField = value;
}
}
}
CodePudding user response:
You are missing the namespace declaration on your root object ServiceABC
.
You also appear to have incorrect nested objects: nil="true"
just means it's a nullable field. I'd have to guess what the real types are due to lack of information.
[XmlRoot(ElementName="Service.ABC", Namespace = "http://schemas.datacontract.org/2004/07/Services.Public")]
public class ServiceABC
{
[XmlElement(ElementName="Amount")]
public int? Amount { get; set; }
[XmlElement(ElementName="CustomerID")]
public int? CustomerID { get; set; }
[XmlElement(ElementName="ID")]
public int ID { get; set; }
[XmlElement(ElementName="UpdatedDate")]
public DateTime? UpdatedDate { get; set; }
}