1

Im trying to Deserialize a XML im getting from a service. But the XmlSerializer failes when encountering the first attribute.

My shortened xml looks like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:basicInformation xmlns:ns2="http://fu.bar.com/">
   <somenode>...</somenode>
   ...
</ns2:basicInformation>

My class looks like this

[XmlRoot(ElementName = "basicInformation")]
public class BasicInformation
{
  [XmlElement(ElementName = "somenode")]
  public string SomeNode { get; set; }

  ...

  [XmlAttribute(AttributeName = "ns2")]
  public string Ns2 { get; set; }

  [XmlText]
  public string Text { get; set; }
}

The error i get is this:

"There is an error in XML document (1, 57)."}
Data: {System.Collections.ListDictionaryInternal}
HResult: -2146233079
HelpLink: null
InnerException: {"<basicInformation xmlns='http://message.async.dms.svap.deere.com/'> was not expected."}
Message: "There is an error in XML document (1, 57)."
Source: "System.Xml"
StackTrace: "   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)\r\n   at System.Xml.Serialization.XmlSerializer.Deserialize(TextReader textReader)\r\n   at AzureQueue.Program.Blurg() in E:\\_Code_\\Testing\\AzureQueue\\AzureQueue\\Program.cs:line 432\r\n   at AzureQueue.Program.<DoSomething>d__1.MoveNext() in E:\\_Code_\\Testing\\AzureQueue\\AzureQueue\\Program.cs:line 71"
TargetSite: {System.Object Deserialize(System.Xml.XmlReader, System.String, System.Xml.Serialization.XmlDeserializationEvents)}

If I replace the second line in the xaml from this:

<ns2:basicInformation xmlns:ns2="http://fu.bar.com/">

to this:

<basicInformation>

everything works just fine.

So it's something with that attribute that im not handeling correctly, but I haven't been able to find a solution.

I should mention that the C# class was generated from a xml to c# tool because the full xml is huge.

So what am I missing? I could solve this the really ugly way and do a string replace but that feels very wrong! ;)

Update

I have accepted @Marc Gravell answer, it works. But i choose to go with the @Denis Micheal solution because it solves my my problem without having to put namespaces on all the XML nodes in my c# models

3
  • 1
    xmlns: doesn't introduce an attribute, but a namespace declaration. Commented Nov 2, 2023 at 16:42
  • Does this answer your question? XML Serialization and namespace prefixes Commented Nov 2, 2023 at 20:20
  • if you wanted to hide the namespace URL, you have included it in the error code. Commented Nov 2, 2023 at 23:53

2 Answers 2

2
[XmlRoot(ElementName = "basicInformation", Namespace = "http://fu.bar.com/")]
public class BasicInformation

Your data is namespace-qualified, and that matters. You may need to apply this individually to child elements, too, but: take that as it comes.

Sign up to request clarification or add additional context in comments.

4 Comments

I tried this. And now the Deserialization didn't throw an error. BUT, the resulting BasicInformation object returned contained all null values.
@merger then the child elements need their namespace correctly specifying - I suspect to "" in this case (explicitly)
Namespaces are difficult
You were correct! When i modified my C# classes to include a Empty namespace - [XmlElement(ElementName = "somenode",Namespace ="")]- it deserialized correctly!
1

Like @Marc Gravell pointed out your xml data has a namespace that you need to also take into account when deserializing. If you want to ignore the namespace that comes with the data,You could create a custom xml reader to ignore the namespace

 public class IgnoreNamespaceXmlTextReader : XmlTextReader
 {
     public IgnoreNamespaceXmlTextReader(System.IO.TextReader reader) : base(reader) { }

     public override string NamespaceURI
     {
         get { return ""; }
     }
 }

Then when deserializing


 var serializer = new XmlSerializer(typeof(BasicInformation));
 using (var stringReader = new StringReader(xml))
 {
     
     // Deserialize the XML string into a BasicInformation object
      var basicInfo = (BasicInformation)serializer.Deserialize(new IgnoreNamespaceXmlTextReader(stringReader));
 }

3 Comments

This worked really well. Im gonna do some more tests with this! TY
It is almost always preferable to simply tell it what namespace to expect than to disable namespaces entirely
@Marc Gravell sure , but have had scenarios where deserializing xml was a constant nightmare due to mutable namespaces in the xml data from an external source. The namespaces weren't even pertinent to application logic or data consumed by service.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.