强制 ASP.net webservice 返回 JSON

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1401549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:19:27  来源:igfitidea点击:

Forcing ASP.net webservice to return JSON

web-servicesjsonasmx

提问by Toji

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,但我总是会返回 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(){...});

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 几乎无法使用此功能)。返回任何东西都会搞砸正在手工构建的响应。

采纳答案by deostroll

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。

回答by womp

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,这样您就可以更好地控制输出格式。

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 内容。

回答by C???

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 articleon Rick Strahl's blog talks about the strongly-typed conversion you can do between server side classes and JSON objects from the client.

本文关于强类型的转换,您可以从客户端服务器端类和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 东西完成了一个项目,我对它的性能印象非常深刻。或许值得一看……