我对WCF很新。我所拥有的一点点经验来自于在ASP.NET Web应用程序中使用相当简单的.SVC服务。
我尝试过第一次尝试使用WCF项目,并遇到了一个重要的节目制作者。
我确信大多数人都知道,出于一些奇怪的原因,在一个将customErrors模式设置为On的Web应用程序中
<customErrors mode = “On” />
服务(.ASMX和.SVC)不会向客户端返回异常详细信息。相反,异常和堆栈跟踪被清空,并且消息始终显示为“处理请求时出错”,这一点都没有用。
当服务直接托管在Web应用程序本身内部时,可以通过将服务放在专用文件夹中,并将customErrors设置为“Off”来轻松解决此限制。
但是,我遇到了同样的问题,例外情况不是从单独的WCF项目中的服务返回。事情是,我不知道如何解决这个问题。
简而言之:我需要让我的WCF项目服务向客户端发送REAL异常 - 或者至少是原始异常消息,而不是“处理请求时出错”。
编辑:我应该在这里指出,我想返回异常的原因是我经常通过Ajax(jQuery)从客户端调用这些服务,并希望如果返回消息是“正常”返回(例如,使用绿色文本),则以不同方式格式化返回消息,如果是错误则使用红色文本。我在$ .ajax对象的错误处理程序中处理消息格式,显然只会在服务失败时运行。
我还应该指出,一切正常,自定义错误关闭:
<customErrors mode = “Off” />
所以,我想也许可以设置一些配置属性来阻止ASP.NET运行时在使用customErrors时杀死我的异常。
Here是我在此发现的一些相关信息。
答案 0 :(得分:3)
您还有另一种方法可以捕获您想要冒泡到客户端的异常,并返回服务错误。
还有一些设计工作需要继续进行,因为你必须自己设计故障合同,但它可以让你灵活地将任何你想要的东西返回给客户。因此,您可以设计一个详细说明错误的合同,如果您认为有必要,可以进行堆栈跟踪。
示例:
[DataContract(Namespace = "urn:// or http://....")]
public class ClientNeedsToKnowFault
{
[DataMember]
public List<Error> Errors
{
get { return _errors; }
set { _errors = value; }
}
....
public ClientNeedsToKnowFault() { }
public ClientNeedsToKnowFault(string message)
{
Message = message;
Errors = new List<Error>() { new Error(message) };
}
...
//Helper method to throw
public static void ThrowFault(string message, List<Error> errorList)
{
throw new FaultException<ClientNeedsToKnowFault>(new ClientNeedsToKnowFault(message, errorList));
}
设计故障后,您需要为服务方法添加其他属性。
[FaultContract(typeof(ClientNeedsToKnowFault))]
void MyServiceMethod();
最后一步是扔掉它。正如你在上面看到的那样,我只是放了一个帮助方法来抛出它,因为我觉得FaultException过程有点乱。
我会说这种方法的主要方法是必须在客户端捕获故障。但是,如果信息足够重要,可以返回错误,那么您可能会想要这种复杂性。
答案 1 :(得分:1)
这里真正的答案是你应该总是避免向调用者冒泡实际异常。这里的“ServiceResponse”模式很有用。我们的想法是,您将返回一个“ServiceResponse”类,其中包含您的服务所需的任何响应值,但除了允许您返回Exception对象的属性外,还有一些“IsError”标志。
然后,该服务可以简单地处理所有错误并返回该信息:
public ServiceResponse MyService()
{
try {
// ... do work here
return new ServiceResponse { WhateverReturnValue = true };
} catch(Exception e) {
return new ServiceResponse { IsError = true, Error = e };
}
}
答案 2 :(得分:1)
您可以查看实施IErrorHandler界面以捕获任何异常并返回合同指定的FaultException。