如何让我的WCF服务以RESTful方式传递错误?具体来说,如果调用者将无效的查询字符串参数传递给我的方法,我希望将400或404 HTTP错误返回给用户。当我搜索与WCF相关的HTTP错误状态时,我所能找到的是人们试图解决他们正在接收的错误的页面。我宁愿不只是抛出FaultException
,因为它会转换为500错误,这不是正确的状态代码。
答案 0 :(得分:7)
我在这里找到了一篇有用的文章:http://zamd.net/2008/07/08/error-handling-with-webhttpbinding-for-ajaxjson/。基于此,这就是我提出的:
public class HttpErrorsAttribute : Attribute, IEndpointBehavior
{
public void AddBindingParameters(
ServiceEndpoint endpoint,
BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(
ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(
ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
var handlers = endpointDispatcher.ChannelDispatcher.ErrorHandlers;
handlers.Clear();
handlers.Add(new HttpErrorHandler());
}
public void Validate(ServiceEndpoint endpoint)
{
}
public class HttpErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(
Exception error, MessageVersion version, ref Message fault)
{
HttpStatusCode status;
if (error is HttpException)
{
var httpError = error as HttpException;
status = (HttpStatusCode)httpError.GetHttpCode();
}
else if (error is ArgumentException)
{
status = HttpStatusCode.BadRequest;
}
else
{
status = HttpStatusCode.InternalServerError;
}
// return custom error code.
fault = Message.CreateMessage(version, "", error.Message);
fault.Properties.Add(
HttpResponseMessageProperty.Name,
new HttpResponseMessageProperty
{
StatusCode = status,
StatusDescription = error.Message
}
);
}
}
}
这允许我向我的服务添加[HttpErrors]
属性。在我的自定义错误处理程序中,我可以确保发送我要发送的HTTP状态代码。
答案 1 :(得分:3)
如果您使用的是标准WCF,则FaultException
是正确的方法。如果您不希望这样做并希望成为RESTful,那么您应该使用REST WCF approach(Here is a quick start template for 4.0和3.5)。这完全支持将HTTP状态代码返回给客户端。
答案 2 :(得分:0)
我想实现您提出的相同解决方案,当您想要使用HTTP状态代码时,下面的链接非常完美。
How can I return a custom HTTP status code from a WCF REST method?
您可以访问WebOperationContext
,它具有OutgoingResponse
类型的OutgoingWebResponseContext
属性,该属性具有可以设置的StatusCode
属性。
WebOperationContext ctx = WebOperationContext.Current;
ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;