代码之家  ›  专栏  ›  技术社区  ›  Toji

强制ASP.NET WebService返回JSON

  •  20
  • Toji  · 技术社区  · 15 年前

    我有一个用于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,btw):

        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),但Deostrull引导我找到了我将在不久的将来使用的答案。另外,应该注意的是,这似乎主要是因为我只想下载,可能在所有情况下都不能很好地工作。在任何情况下,下面是我用来得到我想要的结果的代码:

        [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);
        }
    

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

    3 回复  |  直到 15 年前
        1
  •  2
  •   deostroll    15 年前

    以下是两个论坛主题供您参考:

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

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

    我不清楚。他们说集中精力将内容类型设置为application/json。我以前没有使用过WCF,但我认为您可以使用响应对象。

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

        2
  •  11
  •   womp    15 年前

    ASP.NET Web服务是基于SOAP的Web服务。它们总是返回XML。Ajax库出现了,并引入了scriptmethod工具,但它并没有改变它的基本概念。

    你可以做几件事。

    随着WCF的引入,WebMethods已经过时了。你可能会考虑 migrating your web services to WCF ,这样您就可以更好地控制输出格式。

    如果您不想这样做,您可以手动将WebService调用的结果序列化到JSON中,并且服务会将其包装在SOAP头中。然后你就需要去掉肥皂。

        3
  •  1
  •   Cᴏʀʏ bcherry    15 年前

    我只是想把这个扔了,因为之前没有提到过…如果将WebServices与ASP.NET 3.5一起使用,则json是默认的返回格式。它还附带了JSON序列化程序,因此您可以停止使用JavaScriptSerializer。

    This article 在RickStrahl的博客中讨论了可以在服务器端类和来自客户机的JSON对象之间进行的强类型转换。

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