从 .NET Web 服务方法向 Javascript 客户端返回错误条件

Posted

技术标签:

【中文标题】从 .NET Web 服务方法向 Javascript 客户端返回错误条件【英文标题】:Returning error conditions to a Javascript client from a .NET web service method 【发布时间】:2011-08-09 14:28:14 【问题描述】:

这是一个两部分的问题:

1) 更好的方法是什么,让 .NET 将本机对象转换为 JSON,或者使用包装器并自己编码(例如公共字符串 DataTableToJSON(DataTable))

2) 如果第一个问题的答案是前一种方法,如何最好地将错误条件传递给客户端(javascript AJAX 请求,通常使用 jQuery 或在这种特定情况下,Sencha Touch (Ext))?我目前的方法(在这个问题中进一步解释)似乎工作得很好,但有一个问题似乎取决于客户。

我从 Web 服务返回响应的“旧”方式是将所有方法声明为字符串。我已经这样做了几年,效果很好,但感觉有点笨拙。例如:

public string Test()
  try
    Dataset ds = SomeMethodThatReturnsADataSet();
   catch (Exception ex)
    return "ERROR"; 
    //my JS checks for these messages to be sure everything went OK on the server
  
  return DataTable_To_JSON(ds); 
  //at the client this looks something like d:"[[\"Row1Data\"],[\"Row2Data\"]]"

显然这会在客户端产生轻微的开销,因为我们必须有一行额外的 JavaScript,例如 var data = JSON.parse(response.d);

所以最近我意识到,给定 Web 服务中的 ResponseFormat = ResponseFormat.Json 参数,.NET 将处理对一些 .NET 对象进行 JSON 编码(遗憾的是,我无法让 DataTable 类型工作,但这是另一个问题)。所以现在我的网络服务方法看起来更像这样:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, XmlSerializeString = false)]
public List<MyObject> GetMyObjectList(string arg)
  List<MyObject> li = MyObjectClass.GetList(arg);
  if(li.Count > 500)
    //Since we must return a .NET List<MyObject> I can't return strings on error conditions, so this isn't an option:
    return "TOO_MANY_RESULTS";
    //I saw an example somewhere to do this which works _almost_ great:
    throw new Exception("TOO_MANY_RESULTS");
  
  return li;

就像我在代码 cmets 中所说,抛出异常会返回 HTTP 500,并带有格式良好的 JSON 响应,这很容易在 Ext.Ajax.request 中的“失败”回调中捕获和处理,如下所示:(使用 Chrome 和野生动物园)

"Message":"TOO_MANY_RESULTS","StackTrace":" at ...","ExceptionType":"System.Exception"

但是,由于某种原因,在 iPad 上测试应用程序时,我收到“通用”异常消息响应:

"Message":"There was an error processing the request","StackTrace":"","ExceptionType":""

我已经调试并跟踪了代码,它确实在 C# 中遇到了相同的“抛出新异常”行,它在代码的其他部分没有失败。出于某种原因,客户端的请求标头似乎在某种程度上影响了 .NET 决定返回的内容。

有没有人知道如何尝试让 .NET 始终返回我传递给异常的消息?

编辑:在 android 上也正确工作(在服务器响应中获得“TOO_MANY_RESULTS”)。有机会我会尽快测试 iPhone。

编辑 2:在 iPhone 模拟器上正确工作,物理 iPhone 与我们今天的无线点不兼容,无法测试实际设备。

【问题讨论】:

【参考方案1】:

我可以回答第一个问题。除非 JSON 的默认 WCF 处理对您不起作用,否则我不会产生自定义开销。如果我偏离了服务器端的标准 WCF 处理,尤其是对于 REST 实现(这对您的移动方案很有用),我会研究 WCF Web API,它现在已移至 Microsoft 的 AppFabric 团队。您可以在 CodePlex 上找到最新版本(仍处于测试阶段)。仅在需要时才偏离内置内容,因为存在大量编码开销。

不确定问题 #2,因为我在等式的移动端工作不多(我在服务器/API 端工作)。我也不确定 WCF Web API 是否以不同的方式处理这个问题,但建议至少看看这个方向,特别是如果您使用的是 RESTful 服务。我推荐的原因是所有迹象都表明 Web API 是 Microsoft 未来 REST 的方向。

【讨论】:

谢谢 Gregory,我会调查的。在找到正确的实现之前,我尽量不要太深入这个原型。由于 Sencha Touch 是 MVC 风格的,并且似乎需要一个 REST 服务支持它,这听起来像是一个很好的解决方案。 我最终将我的 Web 服务(以前是一个 ASMX)转换为一个 Web 服务,并且我的客户端相关错误问题消失了。现在所有设备都得到相同的响应。仍然对“为什么”感到好奇,但无论如何,切换到 WCF 似乎是解决方案。感谢您的输入

以上是关于从 .NET Web 服务方法向 Javascript 客户端返回错误条件的主要内容,如果未能解决你的问题,请参考以下文章

从 ASP.net 4 Web API 2 项目通过 HttpClient 调用 REST 服务导致异常

。Net核心-具有不同响应回调的多个服务请求

ASP.NET:从 Web 服务方法返回对象列表

添加对 ASP.NET Web API 服务的服务引用

无法使用 asp.net Web 服务将 ajax 标头值传递给我的 Web 服务方法

通过js向授权的asp.net web api请求XLSX文件