最佳实践 - 从Web服务中抛出异常

Ica*_*rus 3 asp.net jquery json web-services asmx

我们有一个ASMX Web服务,我们使用ajax(jQuery)从我们的ASP.NET应用程序调用它.

我们的Web方法的典型示例如下:

[WebMethod]
public void DoSomething(BusinessObject myParameter)
{

    try
    {
       BL.DoSomethingWithParam(myParameter);
    }
    catch(Exception ex)
    { 
        //logic to log the actual exception goes here
        //and then we throw a more user-friendly error as so:
        throw new Exception("Unable to perform action such an such");
    }
}
Run Code Online (Sandbox Code Playgroud)

在客户端,我们会有这样的事情:

$.ajax({
   type: "POST",
   url: "WebService.asmx/DoSomething",
   data: "{}",
   contentType: "application/json; charset=utf-8",
   dataType: "json",
   success: function(result) {
      //do something with result.d
    },
   error: function(xhr, ajaxOptions, thrownError){ 
      alert($.parseJSON(xhr.Response.Text).Message);
   }
});
Run Code Online (Sandbox Code Playgroud)

上面的方法有几个问题,我想解决这个问题:

  1. 当我们在我们的盒子上本地测试我们的应用程序时,Internet Explorer会在我们的Web方法上显示我们抛出新的Exception行的实际错误消息(在提供的示例代码的情况下:"无法执行此类操作等")但是当我们部署到舞台环境并远程测试时; 它不再显示我们抛出的错误,而是显示:"There has been an error processing your request."
  2. 在Firefox上(我们没有测试更多浏览器),它根本不显示任何内容,但Firebug显示抛出了HTTP 500错误.

总之,我们没有适当地处理这个问题,所以我的问题是:

  1. 在本地和远程测试时,将这些错误传达给客户端并在所有浏览器中具有一致行为的最佳方法是什么?
  2. 为什么IE不像Firefox那样破坏?当然,通过不显示真正的错误消息并将其替换为通用There has been an error processing your request而远程测试IE中断,但为什么Firefox不会这样做呢?
  3. 考虑到该Web服务也将被公司内的其他Java Web应用程序使用这一事实,维护这些应用程序的互操作性的最佳方法是什么?我们怎样才能在Web方法上抛出这些异常,让Java应用程序能够捕获它们并适当地处理它们?

我们实现的一个替代方案 - 现在,我们仍然处于开发阶段 - 只是在发生错误时从我们的Web方法返回一个字符串,但这实际上是一种丑陋的黑客/不优雅的方式.

注意:不要问我"处理您的请求时出错"消息来自何处.我没有最微弱的想法.我们的代码中没有任何可以返回该消息的内容.

Spe*_*ort 6

我不知道是否已经出现了一种"正确"的方式,因为Web服务的使用方式正在如此迅速地变化,并且最终构建为使用服务的任何客户端都能够处理您选择的任何方法.我毫不怀疑最终会设计一个,但现在由你决定.

据说这是为了避免我过去看到的一些更常见的陷阱.

  1. 缺乏一致性:如果您的Web服务有多种方法,那么它们可以以相同的方式传达错误,从而使您的方法更容易使用.我个人更喜欢跟随协议栈的脚步并使用某种一致的头.使用公共头构建结果消息,以便在整个客户端代码中使用相同的逻辑来确定方法调用是否成功.
  2. 不支持多个错误消息:有时会发生多个故障.将客户端阻塞到次要错误可能会造成麻烦并减慢调试尝试.
  3. 缺少错误消息的标识:如果错误是特定字段无效的结果,则允许客户端根据您提供的信息以编程方式识别哪个字段是罪魁祸首.

我通常从这些日子开始的方法看起来像这样:

{
    Success: bool,
    Errors[]: {
        Id: string,
        Source: string,
        Message: string
    },
    Message: { *Method specific structure* }
}
Run Code Online (Sandbox Code Playgroud)