短版本:是否有一个/有什么建议的方式来错误的详细信息返回时,一个异常是从刚刚扔的门打开扔在一个支持AJAX的WCF服务(除了客户端和发回所有异常的详细信息)?
Short Version: Is there a/what is the suggested way to return error details to the client when an exception is thrown in an AJAX-Enabled WCF Service (aside from just throwing the gates open and sending back all of the exception details)?
长的版本:
我有一个相对简单的支持AJAX的WCF服务,我是从客户端使用默认服务代理调用。我提供了code段下面,但我不相信有什么毛病code本身。
I've got a relatively simple AJAX-enabled WCF service that I'm calling from the client using the default service proxy. I've provided code snippets below, but I do not believe there is anything wrong with the code per se.
我的问题是,如果我在服务中抛出一个异常,错误对象返回给客户端总是通用的:
My problem is that if I throw an exception in the service, the error object returned to the client is always generic:
{ "ExceptionDetail":null, "ExceptionType":null, "Message":"The server was unable to process the request..." "StackTrace":null }
在理想情况下,我想这取决于什么地方出了错在客户端上显示不同的错误信息。
Ideally I would like to display different error messages on the client depending on what went wrong.
一种选择是允许例外的WCF故障,这会为我提供了完整的堆栈跟踪和一切,但我AP preciate安全顾虑这一点,而这实际上是更多的信息比我更需要。我可以凑合着刚刚能够发送回描述问题什么的字符串,但我不明白的方式来做到这一点。
One option is to allow exceptions in WCF faults, which would provide me with the full stack trace and everything, but I appreciate the security concerns with this, and that's actually a lot more information than I need. I could make do with just being able to send back a string describing the problem or something, but I don't see a way to do this.
我的服务code:
[ServiceContract(Namespace = "MyNamespace")] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class MyService { [OperationContract] public void DoStuff(string param1, string etc) { //Do some stuff that maybe causes an exception } }在客户端:
MyNamespace.MyService.DoStuff( param1, etc, function() { alert("success"); }, HandleError);
在哪里的HandleError是会显示错误的细节只是一个普通的错误处理方法。
where "HandleError" is just a generic error handling method that would display details about the error.
推荐答案编辑:更新后以适当的自定义JSON错误处理程序
Updated the post with a proper custom json error handler
<serviceDebug includeExceptionDetailInFaults="true"/>在您的服务行为会给你你需要的所有细节。
In Your service behavior will give you all the details you need.
所有的应用程序例外是使用 DataContractJsonSerializer 转换为 JsonError 和系列化。该 Exception.Message 直接使用。 FaultExceptions提供故障code和其他异常的threated为未知与故障code -1。
All exceptions from the application are converted to an JsonError and serialized using a DataContractJsonSerializer. The Exception.Message is used directly. FaultExceptions provide the FaultCode and other exception are threated as unknown with faultcode -1.
的FaultException发送HTTP状态code 400和其他的例外是HTTP code 500 - 内部服务器错误。这不nescessary作为故障code可用来决定是否有与未知错误。这是在我的应用程序却方便。
FaultException are sent with HTTP status code 400 and other exceptions are HTTP code 500 - internal server error. This not nescessary as the faultcode can be used to decide if it is and unknown error. It was however convenient in my app.
错误处理程序
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 }
Webbehaviour用于安装上述错误处理程序
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错误格式。 添加的属性在这里更改错误格式。
Specifies the json error format. Add properties here to change the error format.
[DataContractFormat] public class JsonError { [DataMember] public string Message { get; set; } [DataMember] public int FaultCode { get; set; } }
使用错误处理程序
自托管
ServiceHost wsHost = new ServiceHost(new Webservice1(), new Uri("localhost/json")); ServiceEndpoint wsEndpoint = wsHost.AddServiceEndpoint(typeof(IWebservice1), new WebHttpBinding(), string.Empty); wsEndpoint.Behaviors.Add(new AddErrorHandlerBehavior());
的App.config
App.config
<extensions> <behaviorExtensions> <add name="errorHandler" type="WcfServiceLibrary1.ErrorHandlerElement, WcfServiceLibrary1" /> </behaviorExtensions> </extensions>更多推荐
从支持AJAX的WCF服务返回错误详细信息
发布评论