1

Below I have the following objects:

[XmlRoot("ExampleObject")]
public class ExampleObject
{
    [XmlElement("element1")]
    public long element1{ get; set; }

    [XmlElement("element2")]
    public string element2{ get; set; }

    [XmlElement("element3")]
    public string element3{ get; set; }

    [XmlElement("element4")]
    public ExampleObject2 element4{ get; set; }
}

[Serializable()]
public class ExampleObject2
{
    [XmlText]
    public string Value { get; set; }

    [XmlAttribute]
    public string Id { get; set; }

    [XmlAttribute]
    public string Ref { get; set; }   
}

and the following XML:

<c:ExampleObject>
   <c:element1>
        ...
   </c:element1>
   <c:element2>
          ...
   </c:element2>
   <c:element3>
          ...
   </c:element3>
   <c:element4 z:Ref="953" i:nil="true"/> <!--- or this <c:Status z:Id="953">...</c:element4> -->
</ExampleObject>

I am able to get my object perfectly fine, except for element4 where inside ExampleObject2 my Id and Ref are null while Value has the correct value inside.

I want it so that ExampleObject2 always has a Value, it is either null or the value it is supposed to has. I want Id and Ref to be the value of the attribute inside element4 depending on if element4 has that attribute or not.

I was wondering if there's something I am missing?

I have also tried to add specific names for the XMLElement tags like this [XmlAttribute("Id")] but that doesn't seem to do anything. I have also tried including the namespace like this [XmlAttribute("z:Id")] but that causes an error.

I have also tried putting IsNullable within the element4 XMLElement tag but for the XML elements that have nil="true" but it makes the entire ExampleObject2 null which isn't exactly what I am looking for.

I've already looked at the following question and have come to the same issue.

how to deserialize an xml node with a value and an attribute using asp.net serialization

Thank you

user3369494
  • 123
  • 11
  • 1
    Where are you defining the prefix "c"? There should also be a definition for the prefix "z". – jdweng Oct 12 '17 at 16:41
  • Where are "Ref" and "Id" attributes? I only see "z:Ref" and "i:nil" instead. Also try adding text to that element, does it work then? – George Birbilis Oct 12 '17 at 16:47
  • I would need to see valid XML to be certain (where all namespace prefixes are defined) but possibly the following is related: [Deserialize XML element with xsi:nil=“true” in C#](https://stackoverflow.com/q/38018419/3744182). – dbc Oct 12 '17 at 16:49
  • 1
    By the way, that XML looks as though it might have been generated with `DataContractSerializer` with `preserveObjectReferences = true`, rather than with `XmlSerializer`. See [.net XML Serialization - Storing Reference instead of Object Copy](https://stackoverflow.com/a/1617566) or [IsReference property in data contract](https://stackoverflow.com/a/1037949) for examples. Perhaps you should switch to that serializer? With an [mcve] showing the actual namespaces I could say for sure. – dbc Oct 12 '17 at 16:54
  • @jdweng this XML is only a smaller part of a larger XML. But I only want to serialize this portion. I get rid of all the namespaces before I pass it into the serializer and it works fine when putting it into the objects – user3369494 Oct 12 '17 at 16:59
  • @GeorgeBirbilis Ref refers to the z:Ref and Id refers to when the element4 does have a value inside the message, it will have an Id tag instead of a Ref tag – user3369494 Oct 12 '17 at 17:00
  • If you only need to get a small portion of the xml I don't know why you are using the serialize method. Using XmlDocument or XDocument is much more efficient. – jdweng Oct 12 '17 at 17:02
  • based on comment from @dbc, you probably need to add a nil property (see sample at https://stackoverflow.com/questions/38018419/deserialize-xml-element-with-xsinil-true-in-c-sharp) – George Birbilis Oct 12 '17 at 17:12
  • @user3369494 - *this XML is only a smaller part of a larger XML* - that's fine, but we're much more likely to be able to help if you provide a **valid** subset of the XML that we can test load. In particular we need to see the real namespaces corresponding to the prefixes `c:`, `z:` and `i:` – dbc Oct 12 '17 at 17:12
  • @GeorgeBirbilis I have tried adding a nil property and it gets updated correctly when the element4 tag has a nil attribute and the property is set to true or if it doesn't have a nil attribute, the nil property is set to false. But the Id or Ref property still remain at null – user3369494 Oct 12 '17 at 17:54
  • 1
    @GeorgeBirbilis I ended up fixing it with the Nil property like you said and used it with dbc solution to manually naming the namespaces the z: and c: are from. I was only doing one or the other, not both combined. Thank you! – user3369494 Oct 12 '17 at 18:05
  • 1
    Nice - btw, I think you are allowed to add an answer to your own question, though I'm not sure (probably on meta.stackoverflow.com somebody has asked about doing it). – George Birbilis Oct 12 '17 at 18:47
  • Glad to know your problem is resolved. Rather than including the solution in your question, you could [answer your own question](https://stackoverflow.com/help/self-answer) if you want, then accept the answer. That indicates to others the problem is solved so you don't need further help -- and also, what the solution is. – dbc Oct 12 '17 at 19:15

1 Answers1

1

I ended up fixing it with the Nil property like @GeorgeBirbilis said and used it with @dbc's solution to manually naming the namespaces the z: and c: are from. I was only doing one or the other, not both combined. Thank you guys for the help.

[XmlAttribute(Namespace = "http://schemas.microsoft.com/2003/10/Serialization/")]
public int Id { get; set; }

[XmlAttribute(Namespace = "http://schemas.microsoft.com/2003/10/Serialization/")]
public int Ref { get; set; }

private bool _nil;

[XmlAttribute("nil", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public bool Nil
{
    get
    {
        return _nil;
    }
    set
    {
        _nil = value;
    }
}
user3369494
  • 123
  • 11