JQuery AJAX вызов веб-метода httpget (c #) не работает - PullRequest
13 голосов
/ 16 апреля 2010

Я пытаюсь получить доступ к 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

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

В качестве части ответа возвращается HTML для веб-методов страницы.

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

Ответы [ 5 ]

23 голосов
/ 17 апреля 2010

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

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

  1. Переименуйте webmethods.aspx в webmethods.asmx.
  2. Убедитесь, что вы поместили Внутри \ и httpHandlers для расширения asmx (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. Убедитесь, что атрибут [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'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; }
}

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

Я пришел сюда в поисках ответа ... Для других вот ответ.

В целях безопасности методы страницы ASP.Net AJAX поддерживают только запросы POST.

(от https://stackoverflow.com/a/2397521)

2 голосов
/ 16 апреля 2010
//...
data: { "id" : id },
//...

Данные - это объект, а не строка, которая выглядит как объект.

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

//...
data: "id=" + encodeURIComponent(id) + "&otherstuff=" + encodeURIComponent(data),
//...
1 голос
/ 13 июня 2012

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

0 голосов
/ 13 апреля 2017

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

<WebMethod()>
<ScriptMethod(UseHttpGet:= True, ResponseFormat:= ResponseFormat.Json)>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...