2013-06-13 54 views
6

Tôi đang cố thêm nhiều thông tin liên quan đến lỗi SOAP trong ứng dụng khách nguồn mở. Khách hàng được thiết lập để gọi "HandleFault" bất cứ khi nào nó gặp phải bất kỳ lỗi SOAP nào. Phương pháp Xử lý lỗi được hiển thị dưới đây:Cách xử lý ngoại lệ lỗi 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) 
     ); 
    } 

Đây là một phần của lỗi SOAP được thông qua tại như "thông báo" khi tôi cố gắng và làm điều gì đó giống như sự thay đổi số điện thoại sang định dạng không hợp lệ từ khách hàng.

<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> 

Bất cứ khi nào lỗi được gặp, khách hàng chỉ trả lại "Thông điệp yêu cầu tài liệu bị lỗi đó ngăn chặn xử lý yêu cầu.", Tôi muốn bao gồm các "AttributeRepresentationFailure" nút và con các nút trước khi ném lại ngoại lệ trong ứng dụng khách.

Cách tôi hiểu nó là tôi cần phải xác định một lớp Fault có chứa các chi tiết đó để được khử khoáng, để cuộc gọi đến "CreateFault" có thể trả về a. Tôi đã đọc qua http://msdn.microsoft.com/en-us/library/ms733841.aspx nhưng tôi chỉ không hiểu chính xác cách xác định lớp để khách hàng biết loại lỗi nào được ném.

CẬP NHẬT

Ở phía client phương pháp xử lý lỗi tôi thêm

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

Các lỗi luôn bắt gặp dưới lớp lỗi cơ sở "otherFault". Lớp Sơ yếu lý lịch không hợp lệ của tôi được định nghĩa là bên dưới

[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() { 

    } 
} 

Trả lời

1

Tôi đang sử dụng ví dụ toán học từ bài viết bạn đã đề cập đến. Tạo lớp lỗi:

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

Trang trí phương thức của bạn với OperationContract, ví dụ:

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

Tạo đối tượng MathFault của bạn với dữ liệu hợp lý. Quấn và ném nó:

throw new FaultException<MathFault>(yourFault); 

Hy vọng điều này sẽ hữu ích.

+0

cảm ơn! Tôi nghĩ rằng tôi đang đi đúng hướng, nhưng khi xác định lớp Fault của tôi, lớp học đó cần phải trông như thế nào để xử lý đúng lỗi trong ví dụ tôi đã gửi ở trên? Ngoài ra, làm thế nào trong mã khách hàng để tôi xác định những gì lỗi đã được ném, tôi giả định rằng được chăm sóc trong mã 'System.ServiceModel.FaultException.CreateFault'? –

3

Để thêm vào câu trả lời của Fredrik, lớp Lỗi của bạn có thể là bất cứ điều gì bạn cần để truyền tải chi tiết về lỗi tùy chỉnh của bạn cho khách hàng. Nó không phải kế thừa từ một lớp khác hoặc thực hiện một giao diện. Nó chỉ cần được đánh dấu bằng thuộc tính DataContract.

Đối với đánh bắt nó trên các mặt hàng:

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

Cảm ơn @Jason, nhưng lỗi của tôi không bao giờ bị bắt như là một InvalidRepresentation. Nó luôn luôn bị bắt như một FaultException chung. Tôi có DataContract được định nghĩa trong lớp InvalidRepresentation của tôi. Tôi không hiểu làm thế nào nó biết những gì loại lỗi đang được ném ?? –

+0

Về phía dịch vụ, bạn có đang ném lỗi theo cách mà Fredrik mô tả dưới đây không? 'Ném mới FaultException (yourFault);' – Jason

2

tôi là cuối cùng có thể tìm ra một giải pháp cho điều này, nhờ mọi người giúp đỡ! Đây không phải là giải pháp tốt nhất và cần phải được làm sạch, nhưng nó hoạt động trong khi cho đến khi tôi tìm hiểu thêm về WCF và lỗi SOAP. Ngoài ra, tôi không có quyền truy cập vào mã dịch vụ, chỉ cần mã khách hàng. Mã máy khách đang được chạy dưới dạng mô-đun powerhell.

InvalidRepresentationFault Lớp

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; 
} 

}

Khách hàng HandleFault Mã

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; 
     } 
    } 

Bây giờ khi dịch vụ ném một SOAP Fault nó được deserialized vào lớp "RepresentationFailures", mà tôi có thể tùy chỉnh trước khi quay lại ngược dòng (trong trường hợp này là powershell)

+0

trình mô hình mẫu tốt ** FaultException ** to ** Exception **? – Kiquenet

+0

Đừng ném ngoại lệ. Tạo ngoại lệ tùy chỉnh của riêng bạn và chuyển những gì bạn cần vào đó. – nashwan