У меня есть следующий xml, который я хочу десериализовать в класс C#:
<?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>
Я использую следующие классы для десериализации 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; }
}
Проблема в том, что элемент SessionId не десериализуется, я полагаю, из-за несоответствия пространств имен. Я попытался использовать пустую строку в качестве пространства имен, но это тоже не сработало, поскольку оно не распознается во время десериализации.
Мы очень ценим любое понимание проблемы. Спасибо!
@jdweng Я пробовал, но похоже, что это не помогает.
Сделайте SessionId строкой: [XmlElement (ElementName = "SessionId", Namespace = "")] общедоступная строка SessionId {get; набор; }





Во-первых, SessionId имеет неправильное пространство имен. Он наследует это от родителя, вам нужно явно указать, что у него его нет, установив для него пустую строку.
Во-вторых, xsi:type имеет особое значение, вам не следует пытаться десериализовать его. Он используется для указания типа содержимого элемента - в данном случае string - и будет использоваться сериализатором. Подразумевается, что это один из многих приемлемых типов. Самый простой способ определить это - использовать object.
Собирая их вместе, это должно сработать:
[XmlElement(ElementName = "SessionId", Namespace = "")]
public object SessionId { get; set; }
SessionId должен содержать объект string со значением string.
Также отмечу и другие мелочи:
Xsd) как часть модели. Это более низкий уровень, чем у этой модели, и он будет обрабатываться сериализатором.XmlRoot в корнеXmlText там, где нет текста, не нужны.Result необходимо внести изменения, аналогичные приведенным выше.ElementName и AttributeName по умолчанию будут использовать имя свойства, поэтому вам не нужно указывать их, если это то, что вы хотите.Учитывая это, эта модель должна работать:
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; }
}
Вы можете увидеть рабочую демонстрацию здесь. Я внес одно изменение в исходный XML - я изменил значение Result с boolean на true, иначе вы получите исключение, потому что boolean не является допустимым значением для этого типа.
Большое спасибо не только за рабочий ответ, но и за объяснение, я все еще учусь, так что это было чрезвычайно полезно для меня!
Добавьте пространство имен: [XmlElement (ElementName = "SessionId", Namespace = "s1.com/info/ ")]