【发布时间】:2011-11-03 13:10:55
【问题描述】:
我有一组使用 IErrorHandler 包装异常的 SOAP Web 服务,具体来说:
public sealed class ErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
// don't wrap existing fault exceptions
if ((error is FaultException)) return;
// our basic service fault
var businessFault = new BusinessFault { FaultMessage = error.Message, FaultReference = "Internal" };
// Resource based faultReason
var faultReason = new FaultReason(Properties.Resources.BusinessFaultReason);
var faultcode = FaultCodeFactory.CreateVersionAwareSenderFaultCode(InternalFaultCodes.BusinessFailure.ToString(), Service.Namespace);
var faultException = new FaultException<BusinessFault>(
businessFault,
faultReason,
faultcode);
// Create message fault
var messageFault = faultException.CreateMessageFault();
// Create message using Message Factory method
fault = Message.CreateMessage(version, messageFault, faultException.Action);
}
}
我现在为 Json 和 Pox 添加了额外的端点,它们可以正常工作,除非发生异常。对于 Json 端点,FaultException 以 XML 形式返回。
我从其他 SO 帖子中了解到,对于 REST,我最好抛出 WebHttpException:
throw new WebFaultException<BusinessFault>(detail, HttpStatusCode.BadRequest);
或者覆盖 ProvideFault 中的响应消息属性,因此:
var wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json);
fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf);
var rmp = new HttpResponseMessageProperty
{
StatusCode = System.Net.HttpStatusCode.BadRequest,
StatusDescription = "See fault object for more information."
};
fault.Properties.Add(HttpResponseMessageProperty.Name, rmp);
不过,MSDN 对WebHttpException 有一些有趣的评论,即:
当使用 WCF REST 端点(WebHttpBinding 和 WebHttpBehavior 或 WebScriptEnablingBehavior) 响应上的 HTTP 状态码已设置 因此。但是,WebFaultException 可以与非 REST 一起使用 端点和行为类似于常规的 FaultException。
当使用 WCF REST 端点时,序列化的响应格式 故障的确定方式与非故障响应相同。更多 有关 WCF REST 格式的信息,请参阅 WCF REST 格式。
因此建议我需要转换当前的 ProvideFault 方法以提供新的 WebHttpException(包装任何现有的异常或故障异常),然后 SOAP 仍然可以正常工作。
有没有人想试一试那会是什么样子(.Net4.0 btw)?我想要一个错误处理程序来统治它们!
【问题讨论】:
-
我不明白你的问题。您想为 JSON/POX/SOAP 端点单独实现 IErrorHandler 吗?
-
@Cybermaxs 正确。 WCF 允许您向不同类型的客户端公开多个端点。这一切都很好,直到你需要提出错误。如果我(通常)提出 SOAP 错误,那么 HTTP 客户端将不会更明智。如果我提出 HTTP 错误,那么 SOAP 客户端就会被蒙在鼓里。