2013-06-13 4 views
6

Я пытаюсь добавить дополнительную информацию о сбое SOAP в клиентском приложении с открытым исходным кодом. Клиент настроен на вызов «HandleFault» всякий раз, когда он сталкивается с любой ошибкой SOAP. Метод Handle Fault показано ниже:Как удалить исключение WCF

public static void HandleFault(Message message) { 
     MessageFault fault = MessageFault.CreateFault(message, Int32.MaxValue); 
     throw System.ServiceModel.FaultException.CreateFault(fault, 
      typeof(PermissionDeniedFault), 
      typeof(EndpointUnavailable), 
      typeof(InvalidRepresentation), 
      typeof(UnwillingToPerformFault), 
      typeof(CannotProcessFilter), 
      typeof(AnonymousInteractionRequiredFault) 
     ); 
    } 

Вот часть SOAP Fault, который передается как «сообщение», когда я пытаюсь сделать что-то подобное изменение номер телефона недопустимый формат от клиента.

<s:Body u:Id="_2"> 
<Fault xmlns="http://www.w3.org/2003/05/soap-envelope"> 
    <Code> 
    <Value>Sender</Value> 
    <Subcode> 
     <Value xmlns:a="http://schemas.xmlsoap.org/ws/2004/09/transfer">a:InvalidRepresentation</Value> 
    </Subcode> 
    </Code> 
    <Reason> 
    <Text xml:lang="en-US">The request message contains errors that prevent processing the request.</Text> 
    </Reason> 
    <Detail> 
    <RepresentationFailures xmlns="http://schemas.microsoft.com/2006/11/ResourceManagement" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
     <AttributeRepresentationFailure> 
     <AttributeType>OfficePhone</AttributeType> 
     <AttributeValue>(123)456-7890</AttributeValue> 
     <AttributeFailureCode>ValueViolatesRegularExpression</AttributeFailureCode> 
     <AdditionalTextDetails>The specified attribute value does not satisfy the regular expression.</AdditionalTextDetails> 
     </AttributeRepresentationFailure> 
     <CorrelationId>11042dda-3ce9-4563-b59e-d1c1355819a4</CorrelationId> 
    </RepresentationFailures> 
    </Detail> 
</Fault> 

Всякий раз, когда что неисправность встречаются, клиент только возвращается «Сообщение запроса содержит ошибки, которые мешают при обработке запроса.» Я хотел бы включить «AttributeRepresentationFailure» узел и ребенок узлов перед повторным сбросом исключения в клиенте.

Как я понимаю, мне нужно определить класс Fault, который содержит эти детали, которые будут обработаны, так что вызов «CreateFault» может вернуть a. Я прочитал http://msdn.microsoft.com/en-us/library/ms733841.aspx, но я просто не понимаю, как определить класс, чтобы клиент знал, какой тип ошибки будет сброшен.

ОБНОВЛЕНИЕ

В методе повреждения ручки на стороне клиента я добавил

try 
     { 
      throw faultexcept; 
     } 
     catch (System.ServiceModel.FaultException<InvalidRepresentation> invalidRepresentationFault) 
     { 
      throw invalidRepresentationFault; 
     } 
     catch (System.ServiceModel.FaultException otherFault) 
     { 
      throw otherFault; 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 

Неисправность всегда пойманной под базовым классом ошибки «otherFault». Мой класс InvalidRepresentation определен ниже

[DataContract(Namespace = Constants.Rm.Namespace)] 
public class InvalidRepresentation 
{ 
    private string _attributeType; 
    private string _attributeValue; 
    private string _attributeFailureCode; 
    private string _additionalTextDetails; 

    [DataMember] 
    public string AttributeType 
    { 
     get { return _attributeType; } 
     set { _attributeType = value; } 
    } 

    [DataMember] 
    public string AttributeValue 
    { 
     get { return _attributeValue; } 
     set { _attributeValue = value; } 
    } 

    [DataMember] 
    public string AttributeFailureCode 
    { 
     get { return _attributeFailureCode; } 
     set { _attributeFailureCode = value; } 
    } 

    [DataMember] 
    public string AdditionalTextDetails 
    { 
     get { return _additionalTextDetails; } 
     set { _additionalTextDetails = value; } 
    } 


    public InvalidRepresentation() { 

    } 
} 

ответ

1

Я использую математический пример из статьи вы упомянули. Создать класс неисправности:

[DataContract(Namespace="http://Microsoft.ServiceModel.Samples")] 
public class MathFault 
{  
... 
} 

Оформить свой метод OperationContract, например.

[OperationContract] 
[FaultContract(typeof(MathFault))] 
int Divide(int n1, int n2); 

Создайте свой объект MathFault с разумными данными. Оберните его и выбросите:

throw new FaultException<MathFault>(yourFault); 

Надеюсь, что это поможет.

+0

спасибо! Я думаю, что нахожусь на правильном пути, но когда я определяю свой класс Fault, что должен выглядеть этот класс, чтобы правильно обработать ошибку в приведенном выше примере? Кроме того, как в клиентском коде я определяю, что был вызван Fault, я предполагаю, что это позаботится в коде 'System.ServiceModel.FaultException.CreateFault'? –

3

Чтобы добавить ответ Fredrik, ваш класс Fault может быть любым, что вам нужно, чтобы передать детали вашей пользовательской ошибки клиенту. Он не должен наследовать от другого класса или реализовывать интерфейс. Он просто должен быть отмечен атрибутом DataContract.

Как ловить его на стороне клиента:

try 
{ 
    ... 
} 
catch (FaultException<MathFault> mathFault) 
{ 
    // handle a math fault 
} 
catch (FaultException<OtherCustomFault> otherFault) 
{ 
    // handle another type of custom fault 
} 
catch (Exception ex) 
{ 
    // regular exception handling 
} 
+0

Спасибо @Jason, но мой Fault никогда не пойман как InvalidRepresentation. Это всегда воспринимается как общее исключение FaultException. У меня есть DataContract, определенный в моем классе InvalidRepresentation. Я не понимаю, как он знает, какой тип ошибки срабатывает? –

+0

На стороне обслуживания вы бросаете ошибку так, как описано ниже Fredrik? 'Throw new FaultException (yourFault);' – Jason

2

я наконец-то смог найти решение для этого, спасибо всем, кто помог! Это не лучшее решение, и его необходимо очистить, но он работает, пока я не узнаю больше о WCF и SOAP Faults. Кроме того, у меня нет доступа к служебному коду, а именно коду клиента. Клиентский код запускается как модуль powershell.

InvalidRepresentationFault Класс

using System.Runtime.Serialization; 
namespace Client.Faults { 
    public class InvalidRepresentationFault 
    { 
     public InvalidRepresentationFault() {} 
    } 
    [DataContract(Namespace = Constants.Rm.Namespace)] 
    public class RepresentationFailures 
    { 
     [DataMember()] 
     public FailureDetail AttributeRepresentationFailure; 

    [DataContract(Namespace = Constants.Rm.Namespace)] 
    public class FailureDetail 
    { 
     [DataMember(Order = 1)] 
     public string AttributeType; 

     [DataMember(Order = 2)] 
     public string AttributeValue; 

     [DataMember(Order = 3)] 
     public string AttributeFailureCode; 

     [DataMember(Order = 4)] 
     public string AdditionalTextDetails; 
    } 

    [DataMember] 
    public string CorrelationId; 
} 

}

Client HandleFault Код

public static void HandleFault(Message message) { 
     MessageFault fault = MessageFault.CreateFault(message, Int32.MaxValue); 

     //Let the fault exception choose the best fault to handle? 
     System.ServiceModel.FaultException faultexcept = System.ServiceModel.FaultException.CreateFault(fault, 
      typeof(PermissionDeniedFault), 
      typeof(AuthenticationRequiredFault), 
      typeof(AuthorizationRequiredFault), 
      typeof(EndpointUnavailable), 
      typeof(FragmentDialectNotSupported), 
      typeof(InvalidRepresentationFault), 
      typeof(UnwillingToPerformFault), 
      typeof(CannotProcessFilter), 
      typeof(FilterDialectRequestedUnavailable), 
      typeof(UnsupportedExpiration), 
      typeof(AnonymousInteractionRequiredFault), 
      typeof(RepresentationFailures) 
     ); 

     try 
     { 
      throw faultexcept; 
     } 
     catch (System.ServiceModel.FaultException<RepresentationFailures> invalidRepresentationFault) 
     { 
      throw new Exception(
       String.Format(
        "{0}\r\nfor Attribute \"{1}\" with Value \"{2}\"", 
         invalidRepresentationFault.Detail.AttributeRepresentationFailure.AdditionalTextDetails, 
         invalidRepresentationFault.Detail.AttributeRepresentationFailure.AttributeType, 
         invalidRepresentationFault.Detail.AttributeRepresentationFailure.AttributeValue 
        ), 
       invalidRepresentationFault 
      ); 
     } 
     catch (System.ServiceModel.FaultException otherFault) 
     { 
      throw otherFault; 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
    } 

Теперь, когда служба бросает SOAP Fault он получает десериализации в класс "RepresentationFailures", который я могу настроить перед повторным сбросом назад upstream (в этом случае для powershell)

+0

хороший шаблонный указатель ** FaultException ** to ** Exception **? – Kiquenet

+0

Не выбрасывайте исключение. Создайте собственное собственное исключение и передайте то, что вам нужно. – nashwan

 Смежные вопросы

  • Нет связанных вопросов^_^