BizTalk Orchestration: ответ с нетипизированной ошибкой SOAP
У меня есть оркестровка BizTalk 2009 с типом порта запрос-ответ, который публикуется как веб-служба WCF Basic-HTTP. Порт имеет одну операцию, и эта операция имеет сообщения запроса и ответа с соответствующими схемами. После получения запроса на этот порт, есть несколько случаев, когда сообщение об ошибке должно быть возвращено клиенту вместо стандартного ответного сообщения. У меня проблемы с получением верного сообщения об ошибке клиенту. Я хотел бы иметь возможность установить как faultcode
а также faultstring
элементы сообщения о сбое SOAP. Вот что я попробовал:
Добавление сообщения об ошибке типа String: я попытался добавить сообщение об ошибке с типом сообщения string в операцию. В рамках оркестровки я создал строковое сообщение и отправил его в качестве ответа. Ошибка, которая была возвращена клиенту, выглядела так:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</faultcode>
<faultstring xml:lang="en-US"><?xml version="1.0" encoding="utf-8"?>
<string>This is the error message.</string></faultstring>
<detail>
<ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<HelpLink i:nil="true"/>
<InnerException i:nil="true"/>
<Message><?xml version="1.0" encoding="utf-8"?>
<string>This is the error message.</string></Message>
<StackTrace>at Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkAsyncResult.End() ...</StackTrace>
<Type>Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkNackException</Type>
</ExceptionDetail>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
Это почти работает, кроме faultstring
Элемент содержит сериализованную версию xml моей строки вместо самой строки. Я также не могу установить faultcode
элемент.
Добавление сообщения об ошибке типа http://schemas.xmlsoap.org/soap/envelope/#Fault
Я подумал, что смогу убедить BizTalk вернуть сообщение об ошибке в соответствии с тем, что я ожидал бы, если бы построил Fault
элемент и послал это. Поэтому я добавил сообщение об ошибке с типом http://schemas.xmlsoap.org/soap/envelope/#Fault
, построил соответствующее сообщение и отправил его как ответ. Результат был таким же, как указано выше, за исключением того, что вместо строки faultstring
элемент содержал CDATA
раздел со всем сообщением XML, которое я построил внутри.
Так что я застрял сейчас; Я чувствую, что это должно быть простой задачей в BizTalk. Документация по MSDN " Как генерировать исключения ошибок из оркестровок, опубликованных как службы WCF", ничего не говорит о том, "как" генерировать исключения ошибок, за исключением того, что они могут быть выброшены и что вам нужно установить includeExceptionDetailInFaults
в конфигурации (что я уже сделал).
Есть ли у кого-нибудь предложения о том, как это можно сделать в BizTalk 2009?
2 ответа
Я решил эту точную проблему, добавив пользовательский WCF IDispatchMessageInspector, где я читаю текст причины из сериализованного сообщения, а затем возвращаю новое сообщение System.ServiceModel.FaultException, используя десериализованный текст причины.
В оркестровке BizTalk я использую System.String в качестве типа сообщения об ошибке PortType.
public class HandleUntypedSoapFault : IDispatchMessageInspector
{
public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
if (reply.IsFault)
{
MessageBuffer buffer = reply.CreateBufferedCopy(int.MaxValue);
MessageFault messageFault = MessageFault.CreateFault(buffer.CreateMessage(), int.MaxValue);
if (!messageFault.HasDetail)
{
reply = buffer.CreateMessage();
return;
}
using (XmlReader reader = XmlReader.Create(new StringReader(messageFault.Reason.ToString())))
{
reader.MoveToContent();
string _faultText = reader.ReadElementContentAsString();
}
reply = Message.CreateMessage(
reply.Version,
new FaultException(
_faultText,
new FaultCode("client")).CreateMessageFault(),
null);
}
}
}
Теперь SoapFault будет выглядеть примерно так:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring xml:lang="en-US">An untyped SoapFault from my BizTalk orchestration. This text was set in the orchestration.</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
Напомнил об этой длинной теме, в которой я участвовал некоторое время назад: http://social.msdn.microsoft.com/forums/en-US/biztalkr2adapters/thread/f69ec7af-a490-4229-81d4-3d1b41bf9c48/
Они ссылаются на пример SDK, который может вам помочь, но это типизированное (а не нетипизированное, как вы просили) исключение ошибки.