最佳实践 – 从Web服务中抛出exception

我们有一个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"); } } 

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

 $.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); } }); 

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

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

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

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

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

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

我不知道由于使用Web服务的方式变化如此迅速,并且最终构建为使用服务的任何客户端都能够处理您选择的任何方法,因此尚未出现“正确”的方式。 我毫不怀疑最终会设计一个,但现在由你决定。

话虽如此,试图避免我过去看到的一些更常见的陷阱。

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

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

 { Success: bool, Errors[]: { Id: string, Source: string, Message: string }, Message: { *Method specific structure* } }