编辑:使用适当的自定义 json 错误处理程序更新帖子
快速但非首选的方式。
<serviceDebug includeExceptionDetailInFaults="true"/>
在你的服务行为中会给你所有你需要的细节。
好方法
应用程序的所有异常都转换为JsonError 并使用DataContractJsonSerializer 进行序列化。直接使用Exception.Message。 FaultExceptions 提供 FaultCode 和其他异常被威胁为未知错误代码 -1。
FaultException 与 HTTP 状态代码 400 一起发送,其他异常是 HTTP 代码 500 - 内部服务器错误。这不是必需的,因为故障代码可用于确定它是否是未知错误。然而,它在我的应用程序中很方便。
错误处理程序
internal class CustomErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
//Tell the system that we handle all errors here.
return true;
}
public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault)
{
if (error is FaultException<int>)
{
FaultException<int> fe = (FaultException<int>)error;
//Detail for the returned value
int faultCode = fe.Detail;
string cause = fe.Message;
//The json serializable object
JsonError msErrObject = new JsonError { Message = cause, FaultCode = faultCode };
//The fault to be returned
fault = Message.CreateMessage(version, "", msErrObject, new DataContractJsonSerializer(msErrObject.GetType()));
// tell WCF to use JSON encoding rather than default XML
WebBodyFormatMessageProperty wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json);
// Add the formatter to the fault
fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf);
//Modify response
HttpResponseMessageProperty rmp = new HttpResponseMessageProperty();
// return custom error code, 400.
rmp.StatusCode = System.Net.HttpStatusCode.BadRequest;
rmp.StatusDescription = "Bad request";
//Mark the jsonerror and json content
rmp.Headers[HttpResponseHeader.ContentType] = "application/json";
rmp.Headers["jsonerror"] = "true";
//Add to fault
fault.Properties.Add(HttpResponseMessageProperty.Name, rmp);
}
else
{
//Arbitraty error
JsonError msErrObject = new JsonError { Message = error.Message, FaultCode = -1};
// create a fault message containing our FaultContract object
fault = Message.CreateMessage(version, "", msErrObject, new DataContractJsonSerializer(msErrObject.GetType()));
// tell WCF to use JSON encoding rather than default XML
var wbf = new WebBodyFormatMessageProperty(WebContentFormat.Json);
fault.Properties.Add(WebBodyFormatMessageProperty.Name, wbf);
//Modify response
var rmp = new HttpResponseMessageProperty();
rmp.Headers[HttpResponseHeader.ContentType] = "application/json";
rmp.Headers["jsonerror"] = "true";
//Internal server error with exception mesasage as status.
rmp.StatusCode = System.Net.HttpStatusCode.InternalServerError;
rmp.StatusDescription = error.Message;
fault.Properties.Add(HttpResponseMessageProperty.Name, rmp);
}
}
#endregion
}
用于安装上述错误处理程序的网络行为
internal class AddErrorHandlerBehavior : WebHttpBehavior
{
protected override void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{
base.AddServerErrorHandlers(endpoint, endpointDispatcher);
//Remove all other error handlers
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Clear();
//Add our own
endpointDispatcher.ChannelDispatcher.ErrorHandlers.Add(new CustomErrorHandler());
}
}
json 错误数据合约
指定 json 错误格式。
在此处添加属性以更改错误格式。
[DataContractFormat]
public class JsonError
{
[DataMember]
public string Message { get; set; }
[DataMember]
public int FaultCode { get; set; }
}
使用错误处理程序
自托管
ServiceHost wsHost = new ServiceHost(new Webservice1(), new Uri("http://localhost/json"));
ServiceEndpoint wsEndpoint = wsHost.AddServiceEndpoint(typeof(IWebservice1), new WebHttpBinding(), string.Empty);
wsEndpoint.Behaviors.Add(new AddErrorHandlerBehavior());
App.config
<extensions>
<behaviorExtensions>
<add name="errorHandler"
type="WcfServiceLibrary1.ErrorHandlerElement, WcfServiceLibrary1" />
</behaviorExtensions>
</extensions>