WCF HTTP/SOAP Webservice - Возвращение сообщения об исключении в случае ошибок

У меня есть простой веб-сервис HTTP/SOAP WCF, реализация сервиса выглядит примерно так:

public CustomResponse DoSomething(CustomRequest request)
{
    try
    {
        return InternalGubbins.WithErrorHandling.ProcessRequest(request);
    }
    catch
    {
        // Some sort of error occurred that is not gracefully
        // handled elsewhere in the framework
        throw new SoapException("Hmmm, it would seem that the cogs are meshed!", SoapException.ServerFaultCode);
    }
}

Теперь, если это исключение SoapException, я хотел бы сообщение об исключении (т.е. Hmmm, it would seem that the cogs are meshed!) должен быть возвращен вызывающему клиенту без каких-либо дополнительных деталей об исключениях (т. е. следы стека)

Если я установлю includeExceptionDetailInFaults в true (web.config на сервере), то полное исключение со следами стека и т. д. возвращается клиенту. Однако, если я установлю его в false, я получу общее сообщение:

Серверу не удалось обработать запрос из-за внутренней ошибки. Для получения дополнительной информации об ошибке либо включите IncludeExceptionDetailInFaults (либо из ServiceBehaviorAttribute, либо из поведения конфигурации) на сервере, чтобы отправить информацию об исключении обратно клиенту, либо включите трассировку в соответствии с документацией Microsoft .NET Framework 3.0 SDK. и проверьте журналы трассировки сервера.

Итак, вопрос в том, как я могу вернуть свое сообщение SoapException обратно вызывающему клиенту? то есть:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
    <s:Header>
        <a:Action s:mustUnderstand="1">http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher/fault</a:Action>
        <a:RelatesTo>urn:uuid:185719f4-6113-4126-b956-7290be375342</a:RelatesTo>
    </s:Header>
    <s:Body>
        <s:Fault>
            <s:Code>
                <s:Value>s:Receiver</s:Value>
                <s:Subcode>
                    <s:Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</s:Value>
                </s:Subcode>
            </s:Code>
            <s:Reason>
                <s:Text xml:lang="en-GB">Hmmm, it would seem that the cogs are meshed!</s:Text>
            </s:Reason>
        </s:Fault>
    </s:Body>
</s:Envelope>

2 ответа

Решение

Я думаю, что вам нужно объявить FaultContract для операции и использовать FaultException (SoapException предварительно WCF). Я считаю, что WCF не отправляет ошибки клиенту, если они не являются частью договора на обслуживание. Я никогда не пробовал SoapException, но, безусловно, создание FaultException всегда работало хорошо для меня.

[ServiceContract()]    
public interface ISomeService
{
     [OperationContract]
     [FaultContract(typeof(MyFault))]
     CustomResponse DoSomething(CustomRequest request)
}

public class SomeService
{
    public CustomResponse DoSomething(CustomRequest request)
    {
        ...
        throw new FaultException<MyFault>(new MyFault());
    }
}

Если вы не хотите определять пользовательский тип исключения, попробуйте это

try    
{        
    return InternalGubbins.WithErrorHandling.ProcessRequest(request);    
}    
catch    
{
    throw new FaultException("Hmmm, it would seem that the cogs are meshed.");    
}

Это отправит следующий ответ клиенту

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <s:Fault>
      <faultcode>s:Client</faultcode>
      <faultstring xml:lang="en-US">Hmmm, it would seem that the cogs are meshed.</faultstring>
    </s:Fault>
  </s:Body>
</s:Envelope>
Другие вопросы по тегам