JQuery ajax вызов httpget webmethod (С#) не работает

Я пытаюсь получить ajax для доступа к веб-методу в коде. Проблема в том, что я продолжаю получать ошибку "parserror" из метода jQuery onfail.

Если я изменю GET на POST, все будет хорошо. См. Мой код ниже.

Ajax Call

<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>

Используемый URL

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

Как часть ответа, он возвращает html для веб-методов страницы.

Любая помощь будет принята с благодарностью.

Ответ 1

Прежде всего я мог сказать, что вы выбираете не самый простой способ. ScriptMethods легко использовать вместе с ASP.NET ScriptManager, а не с jQuery. Я рекомендую вам лучше использовать JSON-совместимые службы WCF HTTP (лучше как RESTfull Service) вместо ASMX Webservice, которые вы пытаетесь использовать сейчас. Тем не менее, вы можете заставить работать код без использования каких-либо технологий Microsoft на стороне клиента.

Прежде всего проверьте серверную сторону.

  • Переименуйте webmethods.aspx в webmethods.asmx.
  • Убедитесь, что вы разместили Inside of\и httpHandlers для расширения asmx (ScriptHandlerFactory) также существуют в config:

    <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>
    
  • Убедитесь, что атрибут [ScriptService] ([System.Web.Script.Services.ScriptService], если вам нравятся полные имена), установленный для вашего класса, унаследованного от System.Web.Services.WebService.

Теперь вы можете протестировать сервис. Откройте в себе URL-адрес веб-браузера, например http://localhost/webmethods.asmx/AjaxGet?id=li1234 Если вы получите обратно что-то вроде
<?xml version="1.0" encoding="utf-8" ?>
<string xmlns="http://tempuri.org/">li1234</string>

Вы можете быть уверены, что сервисная часть работает нормально.

Примечание: Независимо от "ResponseFormat = System.Web.Script.Services.ResponseFormat.Json" атрибут ответа службы с ответами XML, если "Content-Type: application/json;" не заданы в запросе.

Теперь хорошо исправьте клиентский код. Я надеюсь, что комментарии, которые я поместил в следующем коде, объясняют все.

Еще одно небольшое замечание. В последней части кода я вызываю еще один "сложный" веб-метод:

[WebMethod]
[ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
public OutputData AjaxGetMore (InputData input) {
    return new OutputData () {
        id = input.id,
        message = "it 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; }
}

Теперь только код JavaScript, который использует в некоторых местах плагин JSON, который может быть заменен на 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 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);
        }
    }
});

Ответ 2

//...
data: { "id" : id },
//...

Данные - это объект, а не строка, которая похожа на объект.

Если вы используете строку, она должна быть правильно отформатированной строкой запроса URL-адреса, например:

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

Ответ 3

Я пришел сюда, чтобы найти ответ... Для других, вот ответ.

Из соображений безопасности ASP.NET AJAX поддерживает только запросы POST.

(Из fooobar.com/questions/72222/...)

Ответ 4

Вы также можете проверить http://www.json.org/js.html JSON.stringify, где он принимает объект json в качестве параметра и возвращает строку.

Ответ 5

Для тех, кто использует VB, украсьте свой метод следующим образом:

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