Справочная информация. Я работаю над этим интеграционным решением, где мне нужно реализовать службу 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 игнорировать корень?
Соответствует ли это законопроекту?
[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);
}
}
Измените код на:
[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));
}
}