【问题标题】:Forcing ASP.net webservice to return JSON强制 ASP.net Web 服务返回 JSON
【发布时间】:2009-09-09 19:20:05
【问题描述】:

我有一个用于 Web 应用程序的 ASP.net Web 服务,它根据我调用的函数向我返回 XML 或 JSON 数据。到目前为止,这一直运作良好,但我遇到了问题。我想在我的页面上创建一个“导出”链接,用于下载 JSON 文件。该链接的格式非常简单:

<a href="mywebserviceaddress/ExportFunc?itemId=2">Export This Item</a>

正如您想象的那样,这应该导出项目 2。到目前为止一切顺利,是吗?

问题是,由于我没有明确要求接受的内容类型是 JSON,ASP.net 绝对拒绝返回除 XML 之外的任何内容,这不适合这种情况。代码实质如下:

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public Item ExportItem(int itemId)
    {
        Context.Response.AddHeader("content-disposition", "attachment; filename=export.json"); //Makes it a download

        return GetExportItem(itemId);
    }

尽管我将 ResponseFormat 指定为 JSON,但我总是返回 XML,除非我通过 AJAX 请求此方法(使用 Google Web Toolkit,顺便说一句):

    RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, "mywebserviceaddress/ExportFunc");
    builder.setHeader("Content-type","application/json; charset=utf-8");
    builder.setHeader("Accepts","application/json");
    builder.sendRequest("{\"itemId\":2}", new RequestCallback(){...});

很好,但 AJAX 不会给我一个下载对话框。有什么方法可以强制 ASP.net 将 JSON 返回给我,而不管数据是如何请求的?在我看来,没有手动覆盖这种行为是一个严重的设计疏忽。


快速回答:

首先,让我说我认为 womp 的答案可能是长期发展的更好方法(转换为 WCF),但 deostroll 让我得到了我将在不久的将来使用的答案。另外,应该注意的是,这似乎主要是因为我只想下载,可能在所有情况下都无法正常工作。无论如何,这是我最终用来获得我想要的结果的代码:

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public void ExportItem(int itemId)
    {
        Item item = GetExportItem(itemId);            

        JavaScriptSerializer js = new JavaScriptSerializer();
        string str = js.Serialize(item);

        Context.Response.Clear();
        Context.Response.ContentType = "application/json";
        Context.Response.AddHeader("content-disposition", "attachment; filename=export.json");
        Context.Response.AddHeader("content-length", str.Length.ToString());
        Context.Response.Flush();
        Context.Response.Write(str);
    }

请注意 void 的返回类型(这意味着您的 WDSL 将对该功能几乎无用)。返回任何东西都会破坏手工构建的响应。

【问题讨论】:

    标签: web-services json asmx


    【解决方案1】:

    Asp.net Web 服务是基于 SOAP 的 Web 服务。它们总是返回 XML。 Ajax 库出现了,并且引入了 ScriptMethod 的东西,但它并没有改变它的基本概念。

    你可以做几件事。

    随着 WCF 的引入,WebMethods 已经过时了。您可以考虑migrating your web services to WCF,在其中您可以更好地控制输出格式。

    如果您不想这样做,您可以手动将 Web 服务调用的结果序列化为 JSON,该服务会将其包装在 SOAP 标头中。然后你需要去掉 SOAP 的东西。

    【讨论】:

    • 我绝对认为这是“更好”的答案,但不幸的是,我现在没有时间进行全面的转换。不过,这是我将在未来项目中采用的路线。感谢您的提示。
    • 如果他们不支持 JSON 并且“总是返回 XML”,那么这个装饰器是干什么用的? [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    【解决方案2】:

    这里有两个论坛主题供您参考:

    http://forums.asp.net/t/1118828.aspx

    http://forums.asp.net/p/1054378/2338982.aspx#2338982

    我没有明确的想法。他们说专注于将内容类型设置为 application/json。我以前没有使用过 wcf,但我认为您可以使用 Response 对象。

    在响应对象上设置内容类型。执行 response.write 将您的 json 数据作为字符串传递,然后执行 response.end。

    【讨论】:

    • 这两个链接都显示了在使用 AJAX 请求时如何正确检索 JSON 数据。正如我所提到的,我的 AJAX 工作正常,但在不能选择 AJAX 的情况下,我需要恢复 JSON。问题的核心是,在服务器端,我如何强制始终返回 AJAX。
    • (哦,在我之前的评论中,它应该是“在服务器端如何强制 JSON 始终返回”
    • 你试过操纵响应对象吗?查看以下 url 中提到的代码,以获取 ref example-code.com/vbdotnet/aspdotnet_zip_response.asp 您可以使用 httpcontext.current.response 访问响应对象。希望这会有所帮助。
    • 最后一个链接为我做了。进行了一些调整,但它可以工作(问题中发布的代码供参考)。谢谢!
    • 嘿,你没有编辑你自己的问题,而是回答了你自己的问题……他们为此给了你徽章!
    【解决方案3】:

    我只是想把它扔掉,因为之前没有提到它......如果你使用带有 ASP.NET 3.5 的 WebServices,JSON 是默认的返回格式。它还附带 JSON 序列化程序,因此您可以停止使用 JavascriptSerializer。

    Rick Strahl 博客上的This article 谈到了可以在服务器端类和来自客户端的 JSON 对象之间进行的强类型转换。

    我最近在 .NET 3.5 中使用这个新的 JSON 东西完成了一个项目,我对它的性能印象非常深刻。也许值得一看……

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-19
      • 2012-02-26
      • 2023-04-05
      • 2012-06-20
      • 1970-01-01
      • 2013-05-25
      相关资源
      最近更新 更多