Reputation: 3
I have the following xml that i want to deserialize to a c# class:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://www.s1.com/info/" xmlns:types="http://www.s1.com/info/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<tns:SessionInfo>
<SessionId xsi:type="xsd:string">string</SessionId>
</tns:SessionInfo>
</soap:Header>
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<tns:LoginResponse>
<Result xsi:type="xsd:boolean">boolean</Result>
</tns:LoginResponse>
</soap:Body>
</soap:Envelope>
I am using the following classes in order to deserialize the xml:
public class SessionId
{
[XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Type { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "SessionInfo", Namespace = "http://www.s1.com/info/")]
public class SessionInfo
{
[XmlElement(ElementName = "SessionId")]
public SessionId SessionId { get; set; }
[XmlAttribute(AttributeName = "id", Namespace = "")]
public string Id { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Header
{
[XmlElement(ElementName = "SessionInfo", Namespace = "http://www.s1.com/info/")]
public SessionInfo SessionInfo { get; set; }
}
[XmlRoot(ElementName = "Result", Namespace = "")]
public class Result
{
[XmlAttribute(AttributeName = "type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string Type { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "LoginResponse", Namespace = "http://www.s1.com/info/")]
public class LoginResponse
{
[XmlElement(ElementName = "Result")]
public Result Result { get; set; }
}
[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Body
{
[XmlElement(ElementName = "LoginResponse", Namespace = "http://www.s1.com/info/")]
public LoginResponse LoginResponse { get; set; }
[XmlAttribute(AttributeName = "encodingStyle", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public string EncodingStyle { get; set; }
[XmlText]
public string Text { get; set; }
}
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Header", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public Body Body { get; set; }
[XmlAttribute(AttributeName = "xsi", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xsi { get; set; }
[XmlAttribute(AttributeName = "xsd", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Xsd { get; set; }
[XmlAttribute(AttributeName = "soapenc", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Soapenc { get; set; }
[XmlAttribute(AttributeName = "tns", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Tns { get; set; }
[XmlAttribute(AttributeName = "types", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Types { get; set; }
[XmlAttribute(AttributeName = "soap", Namespace = "http://www.w3.org/2000/xmlns/")]
public string Soap { get; set; }
[XmlText]
public string Text { get; set; }
}
The problem is that the SessionId element is not getting deserialized, I am assuming due to the namespaces mismatch. I tried using an empty string as the namespace but that doesn't work either as it doesn't get recognized during deserialization.
Any insight on the problem is very much appreciated. Thank you!
Upvotes: 0
Views: 95
Reputation: 26213
First, SessionId
has the wrong namespace. It inherits this from the parent, you need to explicitly specify that it doesn't have one by setting it to an empty string.
Secondly, the xsi:type
has a special meaning, you shouldn't try to deserialise this. It's used to indicate the content type of an element - in this case, string
- and will be used by the serialiser. The implication is that this is one of many acceptable types. The simplest way to define this is using object
.
Putting those together, this should work:
[XmlElement(ElementName = "SessionId", Namespace = "")]
public object SessionId { get; set; }
SessionId
should contain a string
object with value string
.
I'd also note various other minor things:
Xsd
) as part of the model. This is lower level than this model and will be handled by the serialiser.XmlRoot
on the rootXmlText
properties where there isn't any textResult
ElementName
and AttributeName
will default to the name of the property, so you don't have to specify these if that's what you wantTaking that into account, this model should work:
public class SessionInfo
{
[XmlElement(Namespace = "")]
public object SessionId { get; set; }
}
public class Header
{
[XmlElement(Namespace = "http://www.s1.com/info/")]
public SessionInfo SessionInfo { get; set; }
}
public class LoginResponse
{
[XmlElement(Namespace = "")]
public object Result { get; set; }
}
public class Body
{
[XmlElement(Namespace = "http://www.s1.com/info/")]
public LoginResponse LoginResponse { get; set; }
[XmlAttribute("encodingStyle", Namespace = "http://schemas.xmlsoap.org/soap/envelope/", Form = XmlSchemaForm.Qualified)]
public string EncodingStyle { get; set; }
}
[XmlRoot(Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement]
public Header Header { get; set; }
[XmlElement]
public Body Body { get; set; }
}
You can see a working demo here. I've made one change to the source XML - I changed the Result
value from boolean
to true
, else you'll get an exception because boolean
isn't a valid value for that type.
Upvotes: 1