如何从Web服务中获取异常?

时间:2012-03-07 16:05:39

标签: wcf web-services exception error-handling

当我从项目解决方案中引用它时,我有一个完美运行的Web服务。一旦我将它上传到远程服务器,它就会开始爆炸。不幸的是,我得到的唯一错误消息是在客户端“faultexception未被用户代码处理”。在Web服务中,我在所有方法中都处理了异常,因此我很确定它会被某个地方捕获,但我不知道如何看待它。我怀疑问题与权限有关,但我无法看到它发生在哪里。

我尝试将错误消息放入对象返回中,但它仍然没有将其输出;像这样的东西:

public bool SetDirectReports(ADUser user)
{
    try
    {
        var adEntry = new DirectoryEntry(string.Format("LDAP://<GUID={0}>", user.Guid), "administrator", "S3cur1ty");
        if (adEntry.Properties["directReports"].Count > 0)
        {
            user.DirectReports = new List<ADUser>();
            foreach (string directReport in adEntry.Properties["directReports"]) //is being returned as full distinguished name
            {
                var dr = new DirectoryEntry(string.Format("LDAP://{0}", directReport), "administrator", "S3cur1ty");
                user.DirectReports.Add(GetUserByGuid(dr.NativeGuid));
            }
            return true;
        }
        else
        {
            user.DirectReports = new List<ADUser>();
            return false;
        }
    }
    catch (Exception ex)
    {
        user.HasError = true;
        user.ErrorMessage = "Error setting direct reports: " + ex.Message;
        return false;
    }

}

但它仍然没有捕获。我希望有更好的方法。我不确定我是否可以添加一些可以将异常输出到控制台或者什么的东西。任何帮助,将不胜感激。 TIA

P.S。这不一定是崩溃的方法,在服务中有一个网络。

4 个答案:

答案 0 :(得分:2)

您应该将所有异常转储到服务器端的日志文件中;向客户端公开错误信息是一种潜在的安全风险,这就是为什么它默认关闭的原因。

如果您确实要向客户端发送异常信息,可以将其打开。如果您正在使用WCF服务,则应为服务行为设置“includeExceptionDetailsInFaults”属性,如本{MSN文章dealing with unhandled exceptions in WCF中所述。完成此操作后,您将在名为FaultException的{​​{1}}上拥有一个属性,该属性本身应为Detail类型。

为了更好地处理错误,您还应该使用ExceptionFaultContract类来查看类型错误;它们的好处是它们不会将通道置于故障状态并且可以正确处理:

FaultException<>

如果您使用的是ASP.NET Web服务,则应在web.config中将try { // do stuff here } catch (Exception ex) { var detail = new CustomFaultDetail { Message = "Error setting direct reports: " + ex.Message }; throw new FaultException<CustomFaultDetail>(detail); } 模式设置为“Off”。这将以HTML格式发回整个异常详细信息,客户端应将其作为其接收的SOAP异常的一部分接收。

答案 1 :(得分:1)

您所看到的错误(“用户代码未处理错误”)正在发生,因为这是一个远程异常,默认情况下仅在本地计算机上显示异常是标准行为。为了使其按预期工作,您需要更改customErrors的{​​{1}}部分并将其设置为web.config

更新:我找到了一个相关的问题:c# exception not captured correctly by jquery ajax

答案 2 :(得分:1)

(三年后......)

这是我提出的解决方案,以及一些示例WCF代码和要捕获的Angular代码,并显示异常消息:

Catching exceptions from WPF web services

基本上,您只需要将您的WCF服务包装在try..catch中,当出现问题时,请设置OutgoingWebResponseContext值。

例如,在此网络服务中,我遇到了异常,这会使我的catch代码设置为OutgoingWebResponseContext值。

看起来很奇怪...然后我返回null,但这样可以正常工作。

public List<string> GetAllCustomerNames()
{
    //  Get a list of unique Customer names.
    //
    try 
    {
        throw new Exception("Oh heck, something went wrong !");

        NorthwindDataContext dc = new NorthwindDataContext();
        var results = (from cust in dc.Customers select cust.CompanyName).Distinct().OrderBy(s => s).ToList();

        return results;
    }           
    catch (Exception ex)
    {
        OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
        response.StatusCode = System.Net.HttpStatusCode.Forbidden;
        response.StatusDescription = ex.Message.Replace("\r\n", "");
        return null;
    }
}

这个try..catch的精彩之处在于,只需对代码进行最少的更改,就会将错误文本添加到HTTP状态,您可以在Google Chrome中看到:

Network tab

如果您没有拥有此try..catch代码,则您只会获得400状态错误,这意味着“错误请求”。

现在,在我们的try..catch到位的情况下,我可以从我的Angular控制器调用我的Web服务,并留意这些错误消息。

$http.get('http://localhost:15021/Service1.svc/getAllCustomerNames')
    .then(function (data) {
        //  We successfully loaded the list of Customer names.
        $scope.ListOfCustomerNames = data.GetAllCustomerNamesResult;

    }, function (errorResponse) {

        //  The WCF Web Service returned an error

        var HTTPErrorNumber = errorResponse.status;
        var HTTPErrorStatusText = errorResponse.statusText;

        alert("An error occurred whilst fetching Customer Names\r\nHTTP status code: " + HTTPErrorNumber + "\r\nError: " + HTTPErrorStatusText);

    });

很酷,嘿?

非常简单,通用且易于添加到您的服务中。

耻辱一些读者认为值得投票。对不起。

答案 3 :(得分:0)

您有几种选择:

1)如果您正在使用WCF,请在服务器上抛出FaultException并在客户端上捕获它。例如,您可以在服务上实现FaultContract,并将异常包装在FaultException中。对here的一些指导。

2)您可以使用Windows Server AppFabric,它可以为IIS中的异常提供更多详细信息。 (但需要一些摆弄才能让它正常工作)

3)为什么不为例外实现某种服务器端日志记录?即使是一个文件,你破译真正发生的事情也是非常宝贵的。依靠客户端传达服务器的内部工作原理并不是一种好的做法(特别是出于安全考虑)。