I have an ASP.net web service that I'm using for a web application which returns a either XML or JSON data to me, depending on the function I call. This has been working well thus far, but I've run into a problem. I want to create an "export" link on my page that will download a JSON file. The link is formatted very simply:
我有一个ASP.net Web服务,我用于Web应用程序,它向我返回XML或JSON数据,具体取决于我调用的函数。到目前为止,这一直运作良好,但我遇到了一个问题。我想在我的页面上创建一个“导出”链接,它将下载一个JSON文件。链接的格式非常简单:
<a href="mywebserviceaddress/ExportFunc?itemId=2">Export This Item</a>
As you might imagine, this should export item 2. So far so good, yes?
正如您可能想象的那样,这应该导出第2项。到目前为止这么好,是吗?
Problem is that since I'm not specifically requesting that the accepted content type is JSON, ASP.net absolutely refuses to send back anything but XML, which just isn't appropriate for this situation. The code is essentially as follows:
问题是因为我并没有特别要求接受的内容类型是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);
}
Despite my specifying the ResponseFormat as JSON, I always get back XML unless I request this method via AJAX (using Google Web Toolkit, BTW):
尽管我将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(){...});
That's great, but AJAX won't give me a download dialog. Is there any way to force ASP.net to give me back JSON, regardless of how the data is requested? It would seem to me that not having a manual override for this behavior is a gross design oversight.
这很好,但是AJAX不会给我一个下载对话框。有没有办法迫使ASP.net给我回JSON,无论数据是如何被请求的?在我看来,没有手动覆盖这种行为是一个严重的设计疏忽。
QUICK ANSWER:
快速回答:
First off, let me say that I think that womp's answer is probably the better way to go long term (Convert to WCF), but deostroll led me to the answer that I'll be using for the immediate future. Also, it should be noted that this seems to work primarily because I wanted just a download, may not work as well in all situations. In any case, here's the code that I ended up using to get the result I wanted:
首先,让我说我认为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);
}
Please note the return type of void (which means that your WDSL will be next to useless for this function). Returning anything will screw up the response that is being hand-built.
请注意void的返回类型(这意味着您的WDSL将对此功能无用)。返回任何东西都会搞砸手工制作的响应。
3 个解决方案
#1
2
Here are two forums threads for your reference:
以下是两个论坛帖子供您参考:
http://forums.asp.net/t/1118828.aspx
http://forums.asp.net/t/1118828.aspx
http://forums.asp.net/p/1054378/2338982.aspx#2338982
http://forums.asp.net/p/1054378/2338982.aspx#2338982
I have no clear idea. They say on concentrating on setting the content type to application/json. I haven't worked with wcf before, but I think you can make use of the Response object.
我不清楚。他们说集中精力将内容类型设置为application / json。我之前没有使用过wcf,但我认为你可以使用Response对象。
Set the content type on the response object. Do a response.write passing your json data as string and then do a response.end.
在响应对象上设置内容类型。做一个response.write将你的json数据作为字符串传递,然后做一个response.end。
#2
11
Asp.net web services are SOAP-based web services. They'll always return XML. The Ajax libraries came along and the ScriptMethod stuff was introduced, but it doesn't change the underlying concept of it.
Asp.net Web服务是基于SOAP的Web服务。他们总是会返回XML。出现了Ajax库并引入了ScriptMethod,但它并没有改变它的基本概念。
There's a couple things you can do.
你可以做几件事。
WebMethods are borderline obsolete with the introduction of WCF. You might consider migrating your web services to WCF, in which you'll have much greater control over the output format.
随着WCF的引入,WebMethods已经过时了。您可以考虑将Web服务迁移到WCF,在WCF中您可以更好地控制输出格式。
If you don't want to do that, you can manually serialize the result of your webservice calls into JSON, and the service will wrap that in a SOAP header. You would then need to strip out the SOAP stuff.
如果您不想这样做,可以手动将Web服务调用的结果序列化为JSON,服务将把它包装在SOAP标头中。然后,您需要删除SOAP内容。
#3
1
Just thought I'd throw this out there since it wasn't mentioned previously... if you use WebServices with ASP.NET 3.5, JSON is the default return format. It also comes along with JSON serializer so you can stop using the JavascriptSerializer.
我以为我会把它扔出去,因为之前没有提到过......如果你在ASP.NET 3.5中使用WebServices,JSON是默认的返回格式。它还附带了JSON序列化程序,因此您可以停止使用JavascriptSerializer。
This article on Rick Strahl's blog talks about the strongly-typed conversion you can do between server side classes and JSON objects from the client.
这篇关于Rick Strahl博客的文章讨论了服务器端类与客户端的JSON对象之间可以进行的强类型转换。
I've recently completed a project using this new JSON stuff in .NET 3.5, and I'm extremely impressed with the performance. Maybe it's worth a look...
我最近在.NET 3.5中使用这个新的JSON东西完成了一个项目,我对性能印象非常深刻。也许它值得一看......
#1
2
Here are two forums threads for your reference:
以下是两个论坛帖子供您参考:
http://forums.asp.net/t/1118828.aspx
http://forums.asp.net/t/1118828.aspx
http://forums.asp.net/p/1054378/2338982.aspx#2338982
http://forums.asp.net/p/1054378/2338982.aspx#2338982
I have no clear idea. They say on concentrating on setting the content type to application/json. I haven't worked with wcf before, but I think you can make use of the Response object.
我不清楚。他们说集中精力将内容类型设置为application / json。我之前没有使用过wcf,但我认为你可以使用Response对象。
Set the content type on the response object. Do a response.write passing your json data as string and then do a response.end.
在响应对象上设置内容类型。做一个response.write将你的json数据作为字符串传递,然后做一个response.end。
#2
11
Asp.net web services are SOAP-based web services. They'll always return XML. The Ajax libraries came along and the ScriptMethod stuff was introduced, but it doesn't change the underlying concept of it.
Asp.net Web服务是基于SOAP的Web服务。他们总是会返回XML。出现了Ajax库并引入了ScriptMethod,但它并没有改变它的基本概念。
There's a couple things you can do.
你可以做几件事。
WebMethods are borderline obsolete with the introduction of WCF. You might consider migrating your web services to WCF, in which you'll have much greater control over the output format.
随着WCF的引入,WebMethods已经过时了。您可以考虑将Web服务迁移到WCF,在WCF中您可以更好地控制输出格式。
If you don't want to do that, you can manually serialize the result of your webservice calls into JSON, and the service will wrap that in a SOAP header. You would then need to strip out the SOAP stuff.
如果您不想这样做,可以手动将Web服务调用的结果序列化为JSON,服务将把它包装在SOAP标头中。然后,您需要删除SOAP内容。
#3
1
Just thought I'd throw this out there since it wasn't mentioned previously... if you use WebServices with ASP.NET 3.5, JSON is the default return format. It also comes along with JSON serializer so you can stop using the JavascriptSerializer.
我以为我会把它扔出去,因为之前没有提到过......如果你在ASP.NET 3.5中使用WebServices,JSON是默认的返回格式。它还附带了JSON序列化程序,因此您可以停止使用JavascriptSerializer。
This article on Rick Strahl's blog talks about the strongly-typed conversion you can do between server side classes and JSON objects from the client.
这篇关于Rick Strahl博客的文章讨论了服务器端类与客户端的JSON对象之间可以进行的强类型转换。
I've recently completed a project using this new JSON stuff in .NET 3.5, and I'm extremely impressed with the performance. Maybe it's worth a look...
我最近在.NET 3.5中使用这个新的JSON东西完成了一个项目,我对性能印象非常深刻。也许它值得一看......