我有一个ASP.net Web服务,我用于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,但除非我通过AJAX(使用Google Web Toolkit,BTW)请求此方法,否则我总是返回XML:

    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将对此功能无用)。返回任何东西都会搞砸手工制作的响应。

有帮助吗?

解决方案

以下是两个论坛帖子供您参考:

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。

其他提示

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

你可以做几件事。

随着WCF的引入,WebMethods已经过时了。您可以考虑将您的Web服务迁移到WCF ,您将在其中对输出格式有更大的控制权。

如果您不想这样做,可以手动将Web服务调用的结果序列化为JSON,服务将把它包装在SOAP标头中。然后,您需要删除SOAP内容。

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

这篇文章关于Rick Strahl博客的强烈论述您可以在服务器端类和客户端的JSON对象之间进行类型转换。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top