Как сериализовать объект в сырой XML

1

Справочная информация. Я работаю над этим интеграционным решением, где мне нужно реализовать службу WCF (BizTalk) с пользовательским контрактом на отказ. Сообщение об ошибке должно выглядеть следующим образом:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
   <s:Body>
      <s:Fault>
         <faultcode>002</faultcode>
         <faultstring>some fault</faultstring>
         <detail>
               <wor:invalidMessageFault xmlns:wor="somenamespace">
                  <faultCode>002</faultCode>
                  <faultReference>Client WebService</faultReference>
                  <faultText>some fault</faultText>
               </wor:invalidMessageFault>
         </detail>
      </s:Fault>
   </s:Body>
</s:Envelope>

До сих пор: я создал специальный инспектор неисправностей, чтобы перехватить сообщение о неисправности и отправить обратно ошибку.

Проблема: мне нужно построить раздел <detail> сообщения о неисправности, и, насколько я понял, только способ сделать это - выгрузить в него необработанный XML-код, потому что в построении сообщения об ошибке,

var faultException = new FaultException<RawXMLString>(raw, fault.faultText, new FaultCode(fault.faultCode)).CreateMessageFault();

Он принимает только объект (который может быть сериализован) как деталь, и я пробовал разные вещи, но я мог построить одно и то же сообщение с объектом.

Наконец, я подумал о том, чтобы использовать пользовательскую сериализацию для генерации точного сообщения,

public class RawXMLString : IXmlSerializable
{
    private string xmlTemplate = @"<wor:invalidMessageFault xmlns:wor="some namespace">
          <faultCode>{0}</faultCode>
          <faultReference>Client WebService</faultReference>
          <faultText>{1}</faultText>
        </wor:invalidMessageFault>";

    public string FaultCode { get; set; }

    public string FaultText { get; set; }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteRaw(string.Format(xmlTemplate,FaultCode,FaultText));
    }
}

Теперь есть еще одна проблема, потому что я не хочу <RawXMLString>, есть ли способ заставить serializer игнорировать корень?

  • 0
    Вы настроены на использование собственного сериализатора? Вы можете легко сконструировать это сообщение с помощью простого объявления XDocument.
  • 0
    Вы предлагаете передать XDocument в FaultException? У меня нет контроля над сериализатором, так как сериализация выполняется WCF.
Теги:
serialization
wcf

2 ответа

1

Соответствует ли это законопроекту?

[XmlRoot(Namespace = "somenamespace",
 ElementName = "invalidMessageFault")]
public class InvalidMessageFault : IXmlSerializable
{
    public string FaultCode { get; set; }

    public string FaultText { get; set; }

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteElementString("faultCode", FaultCode);
        writer.WriteElementString("faultReference", "Client WebService");
        writer.WriteElementString("faultText", FaultText);
    }
}
  • 0
    Почти ... но отсутствует префикс пространства имен, и у меня нет доступа к сериализатору, так как сообщение об ошибке сериализуется WCF, и именно поэтому я использовал IXmlSerializable
  • 0
    Это имеет какое-то значение? (вывод семантически эквивалентен)
Показать ещё 3 комментария
0

Измените код на:

[XmlRoot("wor:invalidMessageFault xmlns:wor=\"some namespace\"")]
public class RawXMLString : IXmlSerializable
{
    private string xmlTemplate = @"<faultCode>{0}</faultCode>
      <faultReference>Client WebService</faultReference>
      <faultText>{1}</faultText>";

    public string FaultCode { get; set; }

    public string FaultText { get; set; }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteRaw(string.Format(xmlTemplate,FaultCode,FaultText));
    }
}
  • 0
    Это дает неверный корневой узел <wor_x003A_invalidMessageFault_x0020_xmlns_x003A_wor_x003D__x0022 _....>
  • 0
    Я дал вам отправную точку, вам нужно установить свое имя и пространство имен
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню