簡體   English   中英

在WCF中使用Enterpise Library 6異常處理應用程序塊嗎?

[英]Using Enterpise Library 6 Exception Handling Application Block with WCF?

我將這三個軟件包加載到我的WCF服務項目中:

EnterpriseLibrary.Common版本6.0.1304.0
EnterpriseLibrary.ExceptionHandling 6.0.1304.0
EnterpriseLibrary.ExceptionHandling.WCF版本6.0.1304.0

這是服務接口和MyTestFault DataContract:

[ServiceContract]
public interface IRepairService
{
    [OperationContract]
    [FaultContract(typeof(MyTestFault))]
    string SaveRepairCode(string failureCode, string description);
}

[DataContract]
public class MyTestFault
{
    #region Member Fields

    private string _message = "An unexpected error occured while executing the service method.";

    #endregion

    #region Properties

    [DataMember]
    public string Message
    {
        get { return _message; }
        set { _message = value; }
    }

    #endregion

    #region Constructor(s)

    public MyTestFault() { }

    #endregion
}

這是該服務的實現:

[ExceptionShielding("TestPolicy")]
public class RepairService : IRepairService
{
    #region Private members

    private WimDAL wimDAL;
    ExceptionManager exManager;

    #endregion

    #region Constructor(s)

    public RepairService()
    {
        wimDAL = new WimDAL();

        var testPolicy = new List<ExceptionPolicyEntry>
        {
            {
                new ExceptionPolicyEntry(
                    typeof(SqlException), 
                    PostHandlingAction.ThrowNewException, 
                    new IExceptionHandler[]
                    {
                        new FaultContractExceptionHandler(
                            typeof(MyTestFault), 
                            "SqlException Occurred.",
                            new NameValueCollection(){ { "Message", "Message" }})
                    }) 
            },
            {
                new ExceptionPolicyEntry(
                    typeof(Exception), 
                    PostHandlingAction.ThrowNewException, 
                    new IExceptionHandler[]
                    {
                        new FaultContractExceptionHandler(
                            typeof(MyTestFault), 
                            "Exception Occurred.",
                            new NameValueCollection(){ { "Message", "Message" }})
                    }) 
            }
        };

        var policies = new List<ExceptionPolicyDefinition>();
        policies.Add(new ExceptionPolicyDefinition(
            "TestPolicy", testPolicy));

        exManager = new ExceptionManager(policies);
    }

    #endregion

    /// <summary>
    /// Insert a new fail code with description into RPCODE.
    /// Duplicate primary key will throw SqlException that should be processed by EHAB
    /// </summary>
    public string SaveRepairCode(string failureCode, string description)
    {
        using (TransactionScope txScope = new TransactionScope())
        {
            WimSQLCommand sc = new WimSQLCommand() { StoredProcedure = "Repair.RPCODE_Insert" };

            sc.Parameters.Add(new SqlParameter("@FailureCode", failureCode));
            sc.Parameters.Add(new SqlParameter("@Desc", description));

            exManager.Process(() => wimDAL.Execute_NonQueryNoReturn(sc), "TestPolicy");

            txScope.Complete();
            return "<Save_Repair_Code></Save_Repair_Code>";
        }
    }
}

現在,我有一個TestClient控制台應用程序,它是同一項目的一部分,該項目具有對該項目的引用和服務引用。 從那里,我調用SaveRepairCode()方法並嘗試捕獲特定的故障異常,如下所示:

ServiceReference1.RepairServiceClient r = new ServiceReference1.RepairServiceClient();

Console.WriteLine("Enter a new repair code:");
string repairCode = Console.ReadLine();
Console.WriteLine("Enter description:");
string description = Console.ReadLine();

try
{
    r.SaveRepairCode(repairCode, description);
}
catch (FaultException<MyTestFault> ex)
{
    //do something
    throw;
}
catch (FaultException fex)
{
    //do something
    throw;
}

最后,我運行控制台應用程序並嘗試保存重復的修復代碼。 我通過調試知道這會導致SqlException發生。 越過SqlException后,我看到“ FaultContractWrapperException未由用戶代碼處理”異常,並且它具有我在“ SqlException發生”策略中指定的消息。 當我跳過該步驟時,我會回到客戶端並看到此錯誤:

未處理CommunicationException
服務器未提供有意義的回復; 這可能是由於合同不匹配,會話過早關閉或內部服務器錯誤引起的。

PS-這是帶有WCF的Enterprise Library 6,我沒有手動更改web.config ...,是的,includeExceptionDetailInFaults設置為false。

我在這里想念什么? 提前致謝。


更新
實例化新的ExceptionManager后,似乎缺少這一行代碼。

ExceptionPolicy.SetExceptionManager(exManager);

很高興看到這一行代碼不在Enterprise Library 6-2013年4月.chm中,而是在“開發人員對Microsoft Enterprise Library-Preview.pdf的開發人員指南”中,第269頁,共90頁。進入客戶端的適當FaultException陷阱。

話雖如此,我仍然無法在客戶端上獲得其他MyTestFault屬性。 例如,如果我將公用字符串StoredProcedureName添加到MyTestFault並將其映射到SqlException的“ Procedure”屬性,則在客戶端上我總是會看到null。 為此,策略的唯一更改是添加映射,如下所示:

new NameValueCollection(){ { "Message", "{Message}" }, { "StoredProcedureName", "{Procedure}" } }

原來這是罪魁禍首。

exManager.Process(() => wimDAL.Execute_NonQueryNoReturn(sc), "TestPolicy");

如果想使用ExceptionManager的Process方法,只需執行您期望潛在異常的命令即可。

wimDAL.Execute_NonQueryNoReturn(sc);

這與“ Microsoft Enterprise Library-Preview.pdf開發人員指南”中所說的不符,但是我認為文檔仍在進行中。 我希望這可以幫助其他人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM