WCF 的 Completed 事件中的异常处理

Exception Handling in WCF's Completed Event

我想知道如何在我的 WCF's 完成的事件方法中捕获异常并将其显示给 MessageBox 中的用户。

我调用 GetProductTypeAsync(); 方法从数据库中获取记录。我想捕获此处发生的任何异常并将其发送到 service_GetProductTypeCompleted 事件,它应该在其中向用户显示 Exception Message

public List<ProductType> GetProductType()
{
    List<ProductType> productType = new List<ProductType>();
    try
    {
        using (SqlConnection con = new SqlConnection(_connectionString))
        {
            SqlCommand cmd = new SqlCommand("usp_Get_ProductType", con);
            cmd.CommandType = CommandType.StoredProcedure;
            con.Open();
            using (SqlDataReader reader = cmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    ProductType pType = new ProductType(Convert.ToInt32(reader["pkProductTypeID"]), reader["Name"].ToString());
                    productType.Add(pType);
                }
            }
        }
    }
    catch(Exception ex)
    {
        //Catch Exception and send to the service_GetProductTypeCompleted Event Method
    }
    return productType;
} 

这是service_GetProductTypeCompleted事件

void service_GetProductTypeCompleted(object sender, GetProductTypeCompletedEventArgs e)
{
    if (e.Result.Count != 0)
    {
        productTypes = e.Result.ToList();
        cboProductType.DataContext = productTypes;
    }
}

当您从 服务 发送 exception 时,客户端会收到一般错误消息:

The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs."

如果你想在客户端捕获特定异常,那么你应该从服务[=]抛出所谓的FaultException 32=]。这些是 肥皂故障 并且可以被任何 消费者 识别。请注意,您的服务消费者并不总是 .NET 消费者,因此不会识别抛出 CLR 异常。这就是为什么您需要 throw Soap exception 的原因。

例如这就是你如何捕捉并抛出 Fault Exception

catch (FaultException<AnyTypeThatCanBeSerialized> ex)
        {
            throw;
        }

阅读 this article 了解有关 wcf Faults

的更多详细信息

FaultException 不会流向 Silverlight。您将需要 return 一个 class 类似于您的服务层中的以下内容:

public class ServiceReturnInformation<T>
{
    public T DataContext { get; set; }

    private IList<string> _warnings;
    public IList<string> Warnings
    {
        get { return _warnings ?? (_warnings = new List<string>()); }
        set { _warnings = value; }
    }

    private IList<string> _errors;
    public IList<string> Errors
    {
        get { return _errors ?? (_errors = new List<string>()); }
        set { _errors = value; }
    }
}  

如果发生异常,您的服务需要捕获异常并设置 Errors/Warnings 属性。

    var result = new ServiceReturnInformation<Employee>();
    try
    {
        // Do something
        result.DataContext = GetEmployee();
    }
    catch (Exception ex)
    {
        result.DataContext = null;
        result.Errors.Add(ex.Message);
    }

    return result;