2011-11-18 27 views
8

Tôi có một dịch vụ WCF nhiều giao diện người dùng tiêu thụ. Khi người dùng không thể truy cập cơ sở dữ liệu, tôi nhận được ngoại lệ trái phép từ DB. Tôi không bắt ngoại lệ ở phía máy chủ và gửi nó cho khách hàng.Tôi tiếp tục nhận dịch vụ WCF ở trạng thái bị lỗi ở phía máy khách. Làm thế nào tôi nên bắt ngoại lệ WCF, mà không vi phạm dịch vụ WCF của tôi?

Trên máy khách (trang asp.net), tôi được xem ngoại lệ - Người dùng không thể truy cập cơ sở dữ liệu, đăng nhập thất bại. Điều này là tốt. Nhưng ... nếu tôi thực hiện một cuộc gọi đến dịch vụ WCF một lần nữa, tôi nhận được ngoại lệ là dịch vụ đang ở trạng thái bị lỗi. Chỉ mở là khởi động lại toàn bộ dịch vụ WCF. Dịch vụ WCF được lưu trữ dưới dạng dịch vụ cửa sổ.

Cách tốt nhất để nắm bắt ngoại lệ, đăng nhập ngoại lệ trên phía máy chủ, gửi chi tiết ngoại lệ cho khách hàng mà không phá vỡ dịch vụ là gì? Cảm ơn

+1

hãy thử sử dụng faultcontract. – Radhi

Trả lời

6

ngoại lệ Unhandled sẽ lỗi truyền thông kênh. Như những người khác đã chỉ ra, một kênh bị lỗi phải được hủy bỏ bằng cách gọi Abort() - kênh không thể đóng và không thể sử dụng lại kênh đó.

Để giải quyết phần khác của câu hỏi, "cách tốt nhất để bắt ngoại lệ, đăng ngoại lệ trên phía máy chủ, gửi chi tiết ngoại lệ cho khách hàng mà không vi phạm dịch vụ?", Bạn cần sử dụng FaultException Class.

Ngoài ra, bạn có thể sử dụng IErrorHandler Interface để kết nối máy chủ dịch vụ để bắt bất kỳ ngoại lệ nào không bị bắt gặp (tức là, trình xử lý lỗi toàn cầu). Có rất nhiều ví dụ về cách làm điều này trên mạng - chỉ cần google cho WCF IErrorHandler.

Dưới đây là một vài:

WCF Exception Handling with IErrorHandler

WCF Extensibility – IErrorHandler

+0

cảm ơn. khi nào tôi nên bắt các trường hợp ngoại lệ và ném ngoại lệ lỗi? trong hợp đồng hoạt động hoặc trong cửa sổ dịch vụ onstart mã tạo ra các đối tượng lưu trữ dịch vụ? – InfoLearner

+0

Bạn sẽ bắt ngoại lệ trong dịch vụ, tuần tự hóa nó như là một hợp đồng lỗi, và sau đó máy khách (hoặc dịch vụ windows) có thể bắt ngoại lệ lỗi trong một khối try-catch. – Tim

+0

Rất rõ ràng, cảm ơn bạn –

1

Xem liên kết sau đó nói về cách WCF khách hàng nên bắt lỗi/trường hợp ngoại lệ và các vấn đề tiềm năng bạn có thể chạy vào với 'sử dụng' tuyên bố trong C#:

http://msdn.microsoft.com/en-us/library/aa355056.aspx

Baiscally bạn cần gọi Abort() trên proxy máy khách của bạn. Điều này sẽ ngay lập tức đặt trạng thái proxy thành Đã đóng.

+0

oh tuyệt vời. Bạn có nghĩ rằng nó là ok để ném ngoại lệ trở lại cho khách hàng từ dịch vụ wcf? – InfoLearner

+0

Tôi nghĩ rằng điều đó thực sự phụ thuộc vào loại ứng dụng bạn đang xây dựng và chiến lược xử lý ngoại lệ chung của bạn là gì. Điều đó đang được nói, nếu đây là ứng dụng của người dùng cuối, bạn có thể muốn cho họ biết điều gì đó đã xảy ra. –

2

Bạn có thể sử dụng mã này để tạo ra một lớp wrapper mà sẽ xử lý đúng cách WCF trường hợp ngoại lệ:

public class ServiceProxyHelper<TProxy, TChannel> : IDisposable 
    where TProxy : ClientBase<TChannel>, new() 
    where TChannel : class 
{ 
    /// 
    /// Private instance of the WCF service proxy. 
    /// 
    private TProxy _proxy; 

    /// 
    /// Gets the WCF service proxy wrapped by this instance. 
    /// 
    public TProxy Proxy 
    { 
     get 
     { 
      if (_proxy != null) 
      { 
       return _proxy; 
      } 
      else 
      { 
       throw new ObjectDisposedException("ServiceProxyHelper"); 
      } 
     } 
    } 

    public TChannel Channel { get; private set; } 

    /// 
    /// Constructs an instance. 
    /// 
    public ServiceProxyHelper() 
    { 
     _proxy = new TProxy(); 
    } 

    /// 
    /// Disposes of this instance. 
    /// 
    public void Dispose() 
    { 
     try 
     { 
      if (_proxy != null) 
      { 
       if (_proxy.State != CommunicationState.Faulted) 
       { 
        _proxy.Close(); 
       } 
       else 
       { 
        _proxy.Abort(); 
       } 
      } 
     } 
     catch (CommunicationException) 
     { 
      _proxy.Abort(); 
     } 
     catch (TimeoutException) 
     { 
      _proxy.Abort(); 
     } 
     catch (Exception) 
     { 
      _proxy.Abort(); 
      throw; 
     } 
     finally 
     { 
      _proxy = null; 
     } 
    } 
} 

Sau đó bạn có thể gọi một dịch vụ như thế này:

using (ServiceProxyHelper<EmailServiceClient, EmailService> svc = 
    new ServiceProxyHelper<EmailServiceClient, EmailService>()) 
{ 
    svc.Proxy.SendMail(fromAddress, fromName, toEmail, toName, message); 
} 
Các vấn đề liên quan