简体   繁体   English

仅当使用Http Get但是web.config设置正确时,ASP.NET WebService错误地返回XML而不是JSON

[英]ASP.NET WebService mistakenly returning XML instead of JSON only when using Http Get but web.config is set up right

Symptom: When I make a web service request (from JQuery using .ajax, to ASP.NET .asmx file), if it is made using GET instead of POST, the .asmx file always returns XML instead of JSON. 症状:当我发出Web服务请求时(从使用.ajax的JQuery到ASP.NET .asmx文件),如果是使用GET而不是POST,则.asmx文件始终返回XML而不是JSON。 If I flip the call back to posts, it responds just fine as JSON. 如果我将回拨转回帖子,它会像JSON一样响应。

Goal: How can I get JSON instead of XML, using HTTP GET? 目标:如何使用HTTP GET获取JSON而不是XML?

I've a fair bit of googling already and it isn't the usual suspects like missing ScriptService or not registering handler in web.config. 我已经有了相当多的谷歌搜索,这不是通常的嫌疑人,如缺少ScriptService或没有在web.config中注册处理程序。 It's behaving like the script handler factory is only working on posts? 它的行为就像脚本处理程序工厂只处理帖子? Please help point me in the right direction here! 请帮助我指出正确的方向!

Server code: 服务器代码:

namespace mynamespace
{
    /// <summary>
    /// Summary description for ServiceAddresses
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    [System.Web.Script.Services.ScriptService]
    public class MyService : System.Web.Services.WebService
    {
        [WebMethod]
        [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true)]
        public string HelloWorld()
        {
            return "Hello World at " + DateTime.Now.ToLongTimeString();
        }
    }
}

Client code: 客户代码:

function testhelloworld(postorget) {
    var webMethod = '/servicedir/MyService.asmx/HelloWorld';
    $.ajax({
        type: ('GET'===postorget)?'GET':'POST',
        url: webMethod,
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        data: "{}",
        success: function(msg) {
            $('#info').text(msg.d);
        },
        error: function(xhr, ajaxOptions, thrownError) {
            $('#info').text('Error: ' + xhr.responseText);
        }
    });
}

Works fine if I switch service to UseHttpGet = false and client requests as POST. 如果切换服务UseHttpGet =虚假和客户端请求的POST工作正常 Sends back XML if I use GET. 如果我使用GET,则返回XML。

Fiddler says request is: Fiddler说请求是:

GET http://myserver/servicedir/MyService.asmx/HelloWorld?{} HTTP/1.1
Host: myserver
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9 ( .NET CLR 3.5.30729)
Accept: application/json, text/javascript, */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
X-Requested-With: XMLHttpRequest
Referer: http://myserver/test/index.aspx

Response: 响应:

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Thu, 14 Oct 2010 00:31:44 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 115

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World at 8:31:44 PM</string>

Relevant parts of web.config: web.config的相关部分:

<webServices>
  <protocols>
    <add name="HttpGet"></add>
    <add name="HttpPost"></add>
  </protocols>
</webServices>
. . .
        <remove verb="*" path="*.asmx"/>
        <add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
 . . .
  <remove name="ScriptHandlerFactory"/>
  <remove name="ScriptHandlerFactoryAppServices"/>
  <add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
        <add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

Same exact thing but recompiling with UseHttpGet = false and requesting via POST works. 同样的事情,但使用UseHttpGet = false重新编译并通过POST请求工作。

Fiddler says POST request is: Fiddler说POST请求是:

POST http://myserver/servicedir/MyService.asmx/HelloWorld HTTP/1.1
Host: myserver
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.9) Gecko/20100824 Firefox/3.6.9 ( .NET CLR 3.5.30729)
Accept: application/json, text/javascript, */*
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: http://myserver/test/index.aspx
Content-Length: 2
Pragma: no-cache
Cache-Control: no-cache

{}

Response: 响应:

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Thu, 14 Oct 2010 00:37:03 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: application/json; charset=utf-8
Content-Length: 33

{"d":"Hello World at 8:37:03 PM"}

Pre-emptively answering the non-answers: 先发制人地回答非答案:

I want to use GET because I would like clients to be able to cache. 我想使用GET,因为我希望客户端能够缓存。

I am aware that there are security concerns with get eg posted on scott gu's blog. 我知道有一些安全问题,例如发布在scott gu的博客上。

I know I could not use ASP.NET's script stuff and just do it myself, or try out Jayrock. 我知道我不能使用ASP.NET的脚本,只是自己动手,或试试Jayrock。 But, I would like to understand why the stock ASP.NET ScriptHandler isn't working. 但是,我想了解为什么库存ASP.NET ScriptHandler不起作用。

Not sure about asmx web services, but we use WCF and it works with these attributes on the method 不确定asmx Web服务,但我们使用WCF并且它在该方法上使用这些属性

[WebGet(RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM