【问题标题】:Calling AJAX enabled web service by POST works but with GET it always return xml通过 POST 调用启用 AJAX 的 Web 服务有效,但使用 GET 它总是返回 xml
【发布时间】:2014-01-20 01:11:54
【问题描述】:

我在 ASP.NET 4.0 网站中以两种不同的方式调用 Web 服务(同一网站中的 asmx 服务)方法。当 asmx Web 服务方法被 [ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)] 修饰时,第一个方法成功并且总是返回一个有效的 JSON 对象。

但是第二种方法失败了,因为返回的数据是 XML 而不是 JSON,即使我已经用 [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] 修饰了 asmx 方法(我不明白为什么使用 GET 时没有返回 JSON但这是在使用POST时?

  • POST服务调用

    var serviceurl = "http://localhost:49441/WebService1.asmx/LoginUser" ;
    $.ajax({
        url: serviceurl,
         type: 'POST', 
          contentType: "application/json; charset=utf-8",
         data: JSON.stringify({ userName: userName, password: password }),
         dataType: "json",
        success: function (msg) {
            alert('Web service call succeeded.  ' + msg.d);
        },
        error: function (error) { alert('ERROR has occurred!'); alert(JSON.stringify(error)) }
    });
    
  • GET服务调用

    var serviceurl = "http://localhost:49441/WebService1.asmx/LoginUser" ;
    $.ajax({
        url: serviceurl,
         type: 'GET', 
          contentType: "application/json; charset=utf-8",
         data: 'userName='+ userName + '&password=' + password,
         dataType: "json",
        success: function (msg) {
            alert('Web service call succeeded.  ' + msg.d);
        },
        error: function (error) { alert('ERROR has occurred!'); alert(JSON.stringify(error)) }
    });
    

  • 编辑 1:

    Web 服务代码如下。使用POST 时,我只需将代码更改为使用UseHttpGet = false 来调用被调用的方法。

    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    [System.Web.Script.Services.ScriptService]
    
    public class WebService1 : System.Web.Services.WebService 
    {
        [WebMethod]
        [PrincipalPermission(SecurityAction.Assert, Unrestricted = true)]
        [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
        public bool LoginUser(string userName, string password)
        {
            bool authenticated = false;
    
            if (userName.ToLower() == "mike" && password.ToLower() == "abcd") 
            {
    
                authenticated = true;
            }
            return authenticated;
        }
    }
    

【问题讨论】:

  • 这里的JS代码没有区别。为了理解为什么在您发布时返回 XML 而不是 JSON,我们需要查看 a) Web 服务代码或 b) Web 服务文档。
  • 好的。让我添加 asmx Web 服务代码。
  • 可能是启用 ajax 的 Web 服务只能通过 POST 而不是 jQuery 的 GET 调用,但不确定。
  • @Sunil jQuery 不关心你使用什么 HTTP 方法。 这不是客户端问题。
  • 好的。当我使用带有 ScriptManager 的标准 JavaScript 方法调用相同的服务方法时,它工作正常,并且当我在 Fiddler 中检查它时它在幕后使用 GET。

标签: jquery asp.net asmx asp.net-4.0


【解决方案1】:

根据我在 Dave Ward 的博客 Explanation on why POST is necessary if we are to receive JSON and not Xml when using jQuery 中的以下 URL 阅读的内容,似乎有必要使用 POST,否则启用 ASP.Net AJAX 的 Web 服务即使它被修饰为返回 JSON,也可以用 XML 响应。我已粘贴上述 URL 中与我的问题相关的部分。

(所以我从这一切中学到的教训是,在从 jQuery 调用启用 AJAX 的 Web 服务(即 asmx 服务)时使用 POST。)

两个简单的要求

正如我之前提到的,一个规定是这些 ScriptServices 仅返回 JSON 序列化结果,如果它们是 要求正确。否则,即使是标有 属性将返回 XML 而不是 JSON。我只能假设那是 误解为 ASMX 服务不能的部分原因 用 JSON 响应。

Scott Guthrie 有一篇关于 从 ScriptServices 中强制 JSON。总而言之,请求 服务方法必须满足两个要求:

(1) Content-Type – HTTP 请求必须声明一个 content-type 应用程序/json。这会通知 ScriptService 它将 以 JSON 格式接收其参数,并且它应该以实物形式响应。

(2) HTTP 方法 - 默认情况下,HTTP 请求必须是 POST 请求。可以绕过这个要求,但它是 建议在处理 JSON 时坚持使用 HTTP POST 请求。

就是这样。

只要满足这两个要求,从低级 XMLHttpRequest 代码到第三方库如 jQuery, 到 ASP.NET AJAX 本身可以很容易地从 ASMX 服务。

【讨论】:

  • 这是正确的(很高兴你找到我的帖子)。将 POST 用于本质上是资源 GET 请求的方法总是感觉有点“错误”,但框架这样做是为了在当时默认情况下确保更高的跨站点安全性。要针对类似的 API 使用 GET(假设您不需要 SOAP),Web API 是较新应用程序的绝佳选择。它与自动序列化和所有内容的工作方式非常相似,但支持 GET、更灵活的 URL 编码输入参数,并且通常是未来的标准方法。
  • Dave - 您的博客非常有用/精彩,并且包含在其他地方难以找到的信息。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多