2010-11-10 36 views
6

Tôi đã tìm kiếm ở khắp mọi nơi để tìm hiểu cách bắt loại hợp đồng lỗi cơ sở trong C#. Tôi muốn có tất cả các hợp đồng lỗi của tôi kế thừa từ một lớp và có một catch (FaultException fex) trong bộ điều khiển MVC.C# WCF bắt ngoại lệ lỗi của loại cơ sở

DataContracts

[DataContract] 
public class BaseClass1 
{ } 

[DataContract] 
public class Class2 : BaseClass1 
{ } 

Dịch vụ

[ServiceContract] 
public interface IService1 
{ 
    [OperationContract] 
    [FaultContract(typeof(BaseClass1))] 
    [FaultContract(typeof(Class2))] //Do I need this one? 
    void ThrowClass2(); 
} 

public class Service1 : IService1 
{ 
    public void ThrowClass2() 
    { 
     throw new FaultException<Class2>(new Class2(), "Class2 Reason"); 
    } 
} 

Dịch vụ tiêu dùng

FaultTestService.Service1Client client = null; 
try 
{ 
    client = new FaultTestService.Service1Client(); 
    client.ThrowAmpFaults("InvalidParameter", 0); 
} 
catch (FaultException<Namespace.BaseClass1> fex) 
{ 
    //DOES NOT GO IN HERE AS I WOULD EXPECT 
} 
catch (FaultException fex) 
{ 
    //Other Possible Option 
    MessageFault fault = fex.CreateMessageFault(); 
    var fe1 = fault.GetDetail<BaseClass1>(); 
    //This throws a serialization exception it needs <Class2> 
} 

Xin vui lòng cho tôi biết nếu một trong những phát biểu khai thác này có thể được cố định để làm những gì tôi đang tìm kiếm.

Trả lời

2

Xin lỗi, không có cách nào để thực hiện việc này. Không có mối quan hệ nào giữa FaultException<T1>FaultException<T2> đơn giản chỉ vì T1 có thể là một phân lớp của T2.

+0

Nhưng lý do của hành vi này là gì? –

5

Cú pháp đó sẽ không hoạt động trong C#. Thay vào đó, hãy xem xét "workaround" folowing.

try 
{ 
    throw new FaultException<DerivedClass2>(new DerivedClass2()); 
} 
catch (FaultException fex) 
{ 
    bool handled = false; 
    Type fexType = fex.GetType(); 
    if (fexType.IsGenericType && fexType.GetGenericTypeDefinition() == typeof(FaultException<>)) 
    { 
     if (typeof(BaseClass1).IsAssignableFrom(fexType.GetGenericArguments()[0])) 
     { 
      object detail = fexType.GetProperty("Detail").GetValue(fex, null); 

      // Use detail here. 

      handled = true; 
     } 
    } 

    if (!handled) 
     throw; // Don't know how to handle. Re-throw. 
} 

Điều này có thể được đơn giản hóa nếu chúng tôi bỏ qua trường hợp bất thường ở đây là Detail == null nhưng loại kết hợp chung được tạo. Tôi cũng sẽ sử dụng từ khóa động C# để đơn giản hóa nó hơn một chút.

try 
{ 
    throw new FaultException<DerivedClass2>(new DerivedClass2()); 
} 
catch (FaultException fex) 
{ 
    bool handled = false; 
    Type fexType = fex.GetType(); 
    if (fexType.IsGenericType && fexType.GetGenericTypeDefinition() == typeof(FaultException<>)) 
    { 
     object detail = ((dynamic)fex).Detail; 
     if (detail is BaseClass1) // true for subclasses too! 
     { 
      // Use detail here. 
     } 

    } 

    if (!handled) 
     throw; // Don't know how to handle. Re-throw. 
} 

Điều khác cần xem xét là bạn chỉ nên sử dụng throw new FaultException<BaseClass1>(new DerivedClass2()). Cách ném này sẽ cho phép bạn bắt đầu sử dụng mã bạn đã cung cấp ban đầu.

0

Khách hàng của bạn cần message inspector. Chúng tôi đã có một số situation tương tự, trong đó máy chủ đang ném nhiều ngoại lệ khác nhau và tất cả đều kết thúc dưới dạng FaultException.

Các vấn đề liên quan