【问题标题】:JQuery ajax call to httpget webmethod (c#) not workingJQuery ajax 调用 httpget webmethod (c#) 不工作
【发布时间】:2011-02-08 17:09:32
【问题描述】:

我正在尝试让 ajax 在后面的代码中访问 web 方法。问题是我不断从 jQuery onfail 方法中收到错误“parserror”。

如果我将 GET 更改为 POST,一切正常。请在下面查看我的代码。

Ajax 调用

<script type="text/javascript">
        var id = "li1234";

        function AjaxGet() {
            $.ajax({
                type: "GET",
                url: "webmethods.aspx/AjaxGet",
                data: "{ 'id' : '" + id + "'}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                async: false,
                success: function(msg) {
                    alert("success");

                },
                error: function(msg, text) {
                    alert(text);
                }
            });
        }

    </script>

代码背后

[System.Web.Services.WebMethod]
[System.Web.Script.Services.ScriptMethod(UseHttpGet = true,
    ResponseFormat = System.Web.Script.Services.ResponseFormat.Json)] 
public static string AjaxGet(string id)
{
    return id;
}

Web.config

        <webServices>
            <protocols>
                <add name="HttpGet"/>
            </protocols>
        </webServices>

正在使用的网址

......../webmethods.aspx/AjaxGet?{%20%27id%27%20:%20%27li1234%27}

作为响应的一部分,它返回页面 webmethods 的 html。

任何帮助将不胜感激。

【问题讨论】:

    标签: c# jquery get


    【解决方案1】:

    首先我要说的是,您选择的方法不是最简单的。 ScriptMethods 很容易与 ASP.NET ScriptManager 一起使用,而不是与 jQuery 一起使用。我会建议你最好使用支持 JSON 的 WCF HTTP 服务(作为 RESTfull 服务更好),而不是你现在尝试使用的 ASMX Web 服务。 不过,无需在客户端使用任何 Microsoft 技术即可让您的代码正常工作。

    首先验证服务器端。

    1. 将 webmethods.aspx 重命名为 webmethods.asmx。
    2. 验证您放置在 \ 的内部,并且配置中也存在 asmx 扩​​展的 httpHandlers (ScriptHandlerFactory):

      <configuration>
        <!-- ... -->
        <system.web>
          <webServices>
            <protocols>
              <add name="HttpGet"/>
            </protocols>
          </webServices>
          <httpHandlers>
            <!-- ... -->
            <add verb="*" path="*.asmx"
                 type="System.Web.Script.Services.ScriptHandlerFactory"
                 validate="false"/>
          </httpHandlers></system.web></configuration>
      
    3. 验证为继承自 System.Web.Services.WebService 的类设置的 [ScriptService] 属性(如果您喜欢全名,则为 [System.Web.Script.Services.ScriptService])。

      李>

    现在您可以测试服务了。在您的 Web 浏览器 URL 中打开,例如 http://localhost/webmethods.asmx/AjaxGet?id=li1234 如果您收到类似
    &lt;?xml version="1.0" encoding="utf-8" ?&gt;
    &lt;string xmlns="http://tempuri.org/"&gt;li1234&lt;/string&gt;

    您可以确定您的维修部件工作正常。

    备注: 独立于“ResponseFormat = System.Web.Script.Services.ResponseFormat.Json”属性,如果“Content-Type:application/json;”,则服务应答带有 XML 响应未在请求中设置。

    现在我们将修复客户端代码。我希望我在下面的代码中放置的 cmets 能解释一切。

    还有一点小评论。在代码的最后一部分,我调用了另一个“复杂”的 web 方法:

    [WebMethod]
    [ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
    public OutputData AjaxGetMore (InputData input) {
        return new OutputData () {
            id = input.id,
            message = "it's work!",
            myInt = input.myInt+1
        };
    }
    

    在哪里

    public class OutputData {
        public string id { get; set; }
        public string message { get; set; }
        public int myInt { get; set; }
    }
    public class InputData {
        public string id { get; set; }
        public int myInt { get; set; }
    }
    

    现在只有在某些地方使用 JSON 插件的 JavaScript 代码,如果有人愿意,可以用 Crockford 的 json2.js 替换它。

    var id = "li1234";
    // version 1 - works
    var idAsJson = '"' + id + '"';  // string serializes in JSON format
    $.ajax({
        type: "GET",
        url: "/webmethods.asmx/AjaxGet?id=" + idAsJson,
        contentType: "application/json; charset=utf-8",
        success: function(msg) {
            alert(msg.d);   // var msg = {d: "li1234"} 
        },
        error: function(res, status) {
            if (status ==="error") {
                // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
                var errorMessage = $.parseJSON(res.responseText);
                alert(errorMessage.Message);
            }
        }
    });
    
    // version 2 with respect of JSON plugin
    $.ajax({
        type: "GET",
        url: "/webmethods.asmx/AjaxGet?id=" + $.toJSON(id),
        contentType: "application/json; charset=utf-8",
        success: function(msg) {
            alert(msg.d);   // var msg = {d: "li1234"} 
        },
        error: function(res, status) {
            if (status ==="error") {
                // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
                var errorMessage = $.parseJSON(res.responseText);
                alert(errorMessage.Message);
            }
        }
    });
    // version 3 where jQuery will construct URL for us
    $.ajax({
        type: "GET",
        url: "/webmethods.asmx/AjaxGet",
        data: {id: $.toJSON(id)},
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        success: function(msg) {
            alert(msg.d);   // var msg = {d: "li1234"} 
        },
        error: function(res, status) {
            if (status ==="error") {
                // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
                var errorMessage = $.parseJSON(res.responseText);
                alert(errorMessage.Message);
            }
        }
    });
    // version 4. We set "Content-Type: application/json" about our data, but we use no 
    //            not 'dataType: "json"' parameter. Then we have "Accept: */*" in the request
    //            instead of "Accept: application/json, text/javascript, */*" before.
    //            Everithing work OK like before.
    $.ajax({
        type: "GET",
        url: "/webmethods.asmx/AjaxGet",
        data: {id: $.toJSON(id)},
        contentType: "application/json; charset=utf-8",
        success: function(msg) {
            alert(msg.d);   // var msg = {d: "li1234"} 
        },
        error: function(res, status) {
            if (status ==="error") {
                // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
                var errorMessage = $.parseJSON(res.responseText);
                alert(errorMessage.Message);
            }
        }
    });
    // version 5. If we don't place "Content-Type: application/json" in our reqest we
    //            receive back XML (!!!) response with "HTTP/1.1 200 OK" header and 
    //            "Content-Type: text/xml; charset=utf-8" which will be placed.
    //            How one can read in
    // http://weblogs.asp.net/scottgu/archive/2007/04/04/json-hijacking-and-how-asp-net-ajax-1-0-mitigates-these-attacks.aspx),
    //             ASP.NET AJAX will not make JSON serialized of response data for
    //             security reasons.
    $.ajax({
        type: "GET",
        url: "/webmethods.asmx/AjaxGet",
        data: {id: $.toJSON(id)},
        dataType: "json",
        //contentType: "application/json; charset=utf-8",
        success: function(msg) {
            alert(msg.d);   // var msg = {d: "li1234"} 
        },
        error: function (res, status, ex) {
            // the code here will be works because of error in parsing server response
            if (res.status !== 200) {   // if not OK
                // we receive exception in the next line, be
                var errorMessage = $.parseJSON(res.responseText);
                alert(errorMessage.Message);
            } else {
                alert("status=" + status + "\nex=" + ex + "\nres.status=" + res.status + "\nres.statusText=" + res.statusText +
                        "\nres.responseText=" + res.responseText);
            }
        }
    });
    // version 6. Send more komplex data to/from the service
    var myData = { id: "li1234", myInt: 100}
    $.ajax({
        type: "GET",
        url: "/webmethods.asmx/AjaxGetMore",
        data: {input:$.toJSON(myData)},
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        success: function(msg) {
            // var msg = {__type: "Testportal.OutputData", id: "li1234", message: "it's work!", myInt:101}
            alert("message=" + msg.d.message + ", id=" + msg.d.id + ", myInt=" + msg.d.myInt); 
        },
        error: function(res, status) {
            if (status ==="error") {
                // errorMessage can be an object with 3 string properties: ExceptionType, Message and StackTrace
                var errorMessage = $.parseJSON(res.responseText);
                alert(errorMessage.Message);
            }
        }
    });
    

    【讨论】:

    • 您的解决方案适用于 asmx Web 服务,但如果 WebMethod 位于 aspx 文件中,是否可以实现此目的?
    • @MattRoberts:一切皆有可能,但我不完全理解其中的原因。 aspx 用于一般的 HTML 寻呼机或 Web 表单。所以对应的Handler会被用来处理对URL的请求。所以文件扩展名的使用非常实用。您可以使用ASHX 创建处理常见 HTTP 请求且没有 UI 或 HTML 标记的通用句柄。
    【解决方案2】:

    我来这里是为了寻找答案……对于其他人来说,这就是答案。

    出于安全原因,ASP.Net AJAX 页面方法仅支持 POST 请求。

    (来自https://stackoverflow.com/a/2397521

    【讨论】:

      【解决方案3】:
      //...
      data: { "id" : id },
      //...
      

      数据是一个对象,而不是看起来像一个对象的字符串。

      如果使用字符串,则必须是格式正确的 URL 查询字符串,如下所示:

      //...
      data: "id=" + encodeURIComponent(id) + "&otherstuff=" + encodeURIComponent(data),
      //...
      

      【讨论】:

      • 这是有道理的。我现在有这个 url ...../webmethods.aspx/AjaxGet?id=li1234 但它仍然返回相同的错误,“parseerror”。
      • @Tim:哦,我现在明白了。您的 GET 请求的 Content-Type 不是 JSON。只需完全忽略该参数即可。响应类型是JSON,所以dataType参数没问题。
      • 谢谢,我现在没有收到错误,尽管它没有命中我的 webmethod,即使它正在返回成功功能。在响应中,我只是从 webwethods 获取 html。很抱歉很痛苦,请帮忙。
      【解决方案4】:

      您还可以查看http://www.json.org/js.html JSON.stringify,它接受一个 json 对象作为参数并返回一个字符串。

      【讨论】:

        【解决方案5】:

        对于那些使用 VB 的人,像这样装饰你的方法:

        <WebMethod()>
        <ScriptMethod(UseHttpGet:= True, ResponseFormat:= ResponseFormat.Json)>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-08-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多