WCF一步一步往前爬(三)

來源:互聯網
上載者:User

第三步:

在用戶端捕獲WCF服務異常。

如果是Debug過程,簡單的方法就是在宿主專案ProductsServiceHost中的app.config檔案中,設定<serviceDebug includeExceptionDetailInFaults="true"/>,或則直接在service

的實作類別上添加ServiceBehavior特性,如下

[ServiceBehavior(IncludeExceptionDetailInFaults=true)]
public class ProductsServiceImpl : IProductsService
{
   ......
}

但是對於Release後的部署的系統,為了增加健壯性。建議在Service端拋出SOAP Faults,用戶端捕獲。拿上一步的ProductsServiceLibrary項目為樣本。

public List<string> ListProducts()
        {
            List<string> p;
            try
            {
                 p = ps.Select(item => item.ProductNumber).ToList();

                 int i = 0;
                 int j = 100 / i;
            }
            catch (Exception e)
            {
                // Edit the Initial Catalog in the connection string in app.config
                // to trigger this exception
                if (e.InnerException is System.DivideByZeroException)
                {
                    throw new FaultException(
                    "Exception Divide By Zero: " +
                    e.InnerException.Message, new FaultCode("Divide"));
                }
                else
                {
                    throw new FaultException(
                    "Exception reading product numbers: " +
                    e.Message, new FaultCode("Iterate through products"));
                }
            }

            return p;
        }

用戶端:

try
{
    // Obtain a list of all products
    ...
    // Fetch the details for a specific product
    ...
    // Query the stock level of this product
    ...
    // Modify the stock level of this product
    ...
    // Disconnect from the service
    ...
}
catch (FaultException e)
{
    Console.WriteLine("{0}: {1}", e.Code.Name, e.Reason);
}

如何?強型別的Faults呢?

namespace ProductsService
{
    // Classes for passing fault information back to client applications
    [DataContract]
    public class SystemFault
    {
        [DataMember]
        public string SystemOperation { get; set; }
        [DataMember]
        public string SystemReason { get; set; }
        [DataMember]
        public string SystemMessage { get; set; }
    }
    [DataContract]
    public class DatabaseFault
    {
        [DataMember]
        public string DbOperation { get; set; }
        [DataMember]
        public string DbReason { get; set; }
        [DataMember]
        public string DbMessage { get; set; }
    }
    // Data contract describing the details of a product
    ....
    // Service contract describing the operations provided by the WCF service
    ....
}

namespace ProductsService
{
    // Service contract describing the operations provided by the WCF service
    [ServiceContract]
    public interface IProductsService
    {
        // Get the product number of every product
        [FaultContract(typeof(SystemFault))]
        [FaultContract(typeof(DatabaseFault))]
        [OperationContract]
        List<string> ListProducts();
        // Get the details of a single product
        ....
        // Get the current stock level for a product
        ....
        // Change the stock level for a product
        ....
    }
}

  public List<string> ListProducts()
        {
            try
            {
                ......
            }
            catch (Exception e)
            {
                // Edit the Initial Catalog in the connection string in app.config
                // to trigger this exception
                if (e.InnerException is System.Data.SqlClient.SqlException)
                {
                    DatabaseFault dbf = new DatabaseFault
                    {
                        DbOperation = "Connect to database",
                        DbReason = "Exception accessing database",
                        DbMessage = e.InnerException.Message
                    };
                    throw new FaultException<DatabaseFault>(dbf);
                }
                else
                {
                    SystemFault sf = new SystemFault
                    {
                        SystemOperation = "Iterate through products",
                        SystemReason = "Exception reading product numbers",
                        SystemMessage = e.Message
                    };
                    throw new FaultException<SystemFault>(sf);
                }
            }
        }

用戶端--

   static void Main(string[] args)
        {
            ...
            try
            {
                ...
            }
            catch (FaultException<SystemFault> sf)
            {
                Console.WriteLine("SystemFault {0}: {1}\n{2}",
                sf.Detail.SystemOperation, sf.Detail.SystemMessage,
                sf.Detail.SystemReason);
            }
            catch (FaultException<DatabaseFault> dbf)
            {
                Console.WriteLine("DatabaseFault {0}: {1}\n{2}",
                dbf.Detail.DbOperation, dbf.Detail.DbMessage,
                dbf.Detail.DbReason);
            }
            catch (FaultException e)
            {
                Console.WriteLine("{0}: {1}", e.Code.Name, e.Reason);
            }
            ...
        }

宿主應用程式中ServiceHost的狀態,

在宿主應用程式中處理Faults

 // ServiceHost object for hosting a WCF service
ServiceHost productsServiceHost;
productsServiceHost = new ServiceHost(...);
...
// Subscribe to the Faulted event of the productsServiceHost object
productsServiceHost.Faulted += (eventSender, eventArgs) =>
{
    // FaultHandler method
    // Runs when productsServiceHost enters the Faulted state
    // Examine the properties of the productsServiceHost object
    // and log the reasons for the fault
    ...
    // Abort the service
   productsServiceHost.Abort();
   // Recreate the ServiceHost object
   productsServiceHost = new ServiceHost(...);
   // Start the service
    productsServiceHost.Open();
};
...

在宿主應用程式中處理用戶端發送過來未知的message

// ServiceHost object for hosting a WCF service
ServiceHost productsServiceHost;
productsServiceHost = new ServiceHost(...);
...
// Subscribe to the UnknownMessageReceived event of the
// productsServiceHost object
productsServiceHost.UnknownMessageReceived += (eventSender, eventArgs) =>
{
    // UnknownMessageReceived event handler
    // Log the unknown message
    ...
    // Display a message to the administrator
    MessageBox.Show(string.Format(
    "A client attempted to send the message: {0} ",
    eventArgs.Message.Headers.Action));
};
...

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.