在我们的应用程序中,所有数据协定都有一个父级 - OperationResponse
,此OperationResponse
包含enum(属性OperationState
中的枚举类型Result
),表示调用结果(确定, InvalidParams ,错误)。
如何在异常后覆盖WCF行为 - 不返回故障状态,但在我的情况下返回经典消息,OperationResponse,但属性为Result = OperationState.Error?
编辑:我想,我正确的方式,我需要实现IErrorHandler,但现在我迷路了,因为我不知道如何将错误信息设置为传出的故障信息...
public bool HandleError(Exception error)
{
// log error
return true; // we catch error and provide our custom message.
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
// create result message
var message = new OperationResponse
{
Result = OperationState.Error
};
// ok how to return message into ref fault?
}
Edit2:如果没有解决方案,这似乎是一个牢不可破的问题......我只找到了相同的问题而没有像this thread这样的解决方案...... :(
答案 0 :(得分:0)
我不确定这正是您正在寻找的,但它是一种相当可管理的方式来处理来自WCF(可能还有其他系统/上下文)的错误。
在这里,我们创建了一个通用的ServiceResponse<T>
,其中可以包含属性Data
中的任何类型的响应,以及Succeeded
和StatusMessage
中的状态信息。
使用CreateServiceResponse()
来排序要在此对象中调用的方法。这样,您可以返回ServiceResponse
Data
设置为该方法的结果。底部有一个使用示例。
也许您可以对此进行调整,以使用OperationResponse
而不是此处使用的OperationState
属性返回Succeeded
的实例?
public class ServiceResponse<T>
{
public ServiceResponse()
{
// Initial default values:
Data = default(T);
Succeeded = true;
StatusMessage = string.Empty;
}
// Indicates whether the attempted operation was completed successfully.
[DataMember]
public bool Succeeded { get; set; }
// Error messages if an operation fails.
[DataMember]
public string StatusMessage { get; set; }
// The main results from any service-call.
[DataMember]
public T Data { get; set; }
[DataMember]
public String InnerExceptionMessage { get; set; }
public static ServiceResponse<T> CreateServiceResponse(Func<T> responseFunc)
{
var response = new ServiceResponse<T>();
try
{
response.Data = responseFunc.Invoke();
}
catch (Exception ex)
{
response = HandleException(responseFunc, ex);
}
return response;
}
private static ServiceResponse<T> HandleException(Func<T> responseFunc, Exception ex)
{
// Handle any exceptions here, and return a ServiceResponse with
// Succeeded = false, and the appropriate messages, etc.
}
}
使用示例(假设GetClients()将返回IEnumerable):
var response = ServiceResponse<IEnumerable<Client>>
.CreateServiceResponse(() => GetClients(clientGroupId));