Возвращая JSON из ASMX и правильно обрабатывая его в Javascript - PullRequest
7 голосов
/ 07 июля 2010

Я понимаю, что здесь уже есть тонны подобных вопросов, но я не могу понять это.

У меня есть веб-сервис (C #, .net 3.5). Основной код, который вам нужно знать, следующий:

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class WSMember : System.Web.Services.WebService {

    public WSMember () {   
    }


    [WebMethod]
    [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
    public string GetMember(string IdMember)
    {
        //Ignore the parameter for now... I will be looking up a database with it... 
        //For now just return a minimal object:
        Member m = new Member();
        m.Surname = "Smith";
        m.FirstName = "John";
        return new JavaScriptSerializer().Serialize(m);
    }

Кроме того, в web.config я сделал следующее дополнение (которое я только что видел в каком-то другом посте ... это нормально / безопасно?)

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

Тогда в Default.aspx, я две ключевые ссылки ...

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
<script type="text/javascript" src="jquery.json-2.2.min.js"  ></script>

jquery.json-2.2.min.js был загружен из кода Google

А вот и Javascript:

<script type="text/javascript">
         $(document).ready(function() {
             $("#button1").click(function(event) {
                 var myData = { IdMember: "2" };
                 var encoded = $.toJSON(myData);

                 alert(encoded);

                 $.ajax({
                     type: "POST",
                     url: "WSMember.asmx/GetMember",
                     data: encoded,
                     contentType: "application/json; charset=utf-8",
                     dataType: "json",
                     success: function(msg) {
                         alert("worked" + msg.d);
                         //$("#sidebar").append(msg);
                     },
                     error: function(msg) {
                         alert(msg.d);
                         //$("#sidebar").append(msg);
                     }
                 });
             });
         });

    </script>

Когда я его выполняю, закодированный json появляется в окне сообщения, как и ожидалось ... то есть с двойными кавычками:

{"IdMember": "2"}

Однако, это всегда терпит неудачу. Даже для самого простого Hello World без передачи данных, это терпит неудачу. Я продолжаю получать "неопределенный" для данных сообщения.

Если я просто использую оповещение (msg), оно отображает [объект XMLHttpRequest]

Кто-нибудь знает, где мои данные теряются ??

И еще один вопрос ... есть ли что-то принципиально неправильное в том, что я делаю?

Большое спасибо.

EDIT:

спасибо за ответ, ребята. Я пробовал следующее, так что ...

UseHttpGet = true теперь изменено на false. (Опять же - я где-то видел это, поэтому я попробовал это ... но я знал, что это не могло быть правильно: - /)

Допустим, веб-сервис теперь возвращает строку. Я строю строку следующим образом (кажется немного сумасшедшим ... сериализация сделала то же самое ...)

    StringBuilder sb = new StringBuilder();
    sb.Append("{");
    sb.Append("\"Surname\":");
    sb.Append("\"");
    sb.Append(m.Surname);
    sb.Append("\"");

    sb.Append(",\"FirstName\":");
    sb.Append("\"");
    sb.Append(m.FirstName);
    sb.Append("\"");

    sb.Append("}");

    return sb.ToString();

Этот код возвращает что-то вроде:

{"Surname":"Smith","FirstName":"John"}

Я все еще получаю ту же ошибку ...

Я также пытался что-то вроде возврата объекта "Member", поэтому код становится:

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public Member GetMember(string IdMember)
{
    Member m = new Member();
    m.Surname = "Smith";
    m.FirstName = "John";

    return m;
}

Это тоже выдает ту же ошибку.

Извините за боль ... Я прочитал и эти ссылки, и другие. Просто не понимаю, почему это так по-другому.

Есть ли какие-либо дополнительные настройки конфигурации, о которых мне нужно знать?

Большое спасибо за ответы.

UPDATE: Проблема исправлена. Ключевые ошибки в приведенном выше коде:

[ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]

должно быть

[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

Также в форме, когда я использовал кнопку для вызова javascript, я неправильно устанавливал тип ввода ...

<input id="button1" type="submit" value="Just a test" />

когда должно сказать:

<input id="button1" type="button" value="Just a test" />

Большое спасибо всем, кто помог.

Ответы [ 5 ]

3 голосов
/ 07 июля 2010

Мне кажется, что ваша основная проблема в том, что вы пытаетесь вручную использовать JavaScriptSerializer().Serialize вместо возврата объекта.Ответ от веб-службы будет в двойном кодировке JSON.

Вы правы!Есть много близких вопросов.Посмотрите здесь Могу ли я вернуть JSON из веб-службы .asmx, если ContentType не является JSON? и Не удается получить jQuery Ajax для анализа результата веб-службы JSON , и вы получите (надеюсь) найти ответ.

ОБНОВЛЕНО : Извините, но у вас есть небольшая ошибка где-то, что вы не опубликовали.Чтобы закрыть проблему, я создал небольшой проект со старой версией Visual Studio (VS2008), в которой практически весь ваш код и которая работает.Я поместил его на http://www.ok -soft-gmbh.com / jQuery / WSMember.zip .Вы можете скачать его, скомпилировать и убедиться, что он работает.Тогда вы можете сравнить свой код с моим и найти вашу ошибку.

С уважением

1 голос
/ 07 июля 2010

Да, определенно не сериализуйте объект вручную.Если вы вернете тип Member, фреймворк будет обрабатывать сериализацию JSON для вас.

Когда вы видите предупреждение [object XMLHttpRequest], похоже, что оно попадает в обработчик ошибок в вашем $.Вызов ajax (), где ответ передается в своем XHR-объекте в качестве первого параметра.Вы, вероятно, получаете ошибку 500 на сервере.

Вот пример декодирования ответа об ошибке ASP.NET AJAX в jQuery .Проще говоря, измените ваш обработчик ошибок на это:

error: function(xhr, status, error) {
  var err = eval("(" + xhr.responseText + ")");

  alert(err.Message);
}

Это даст вам некоторое представление о том, что является конкретной ошибкой.

1 голос
/ 07 июля 2010

Если вы делаете сообщение с вашими данными, почему вы определяете UseHttpGet = true?Разве это не должно быть ложным, чтобы соответствовать типу ответа из вашего запроса?Кроме того, установка точки останова в вызове ws для точного определения того, что возвращает сериализатор, также поможет ... Я не думаю, что он должен возвращать объект JSON, если возвращаемое значение является строкой.

HTH.

0 голосов
/ 03 ноября 2016

Если вы возвращаете какой-либо сложный объект (реляционные объекты с внешними ключами), у вас есть 2 варианта:

  1. Использовать объект DTO
  2. Написать свой собственный определенный преобразователь сериализации
0 голосов
/ 25 февраля 2013

У меня плохой английский, но это решение

----- WSMember.asmx ------

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class WSMember : System.Web.Services.WebService {

     public WSMember () {   
     }

     [WebMethod]
     [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
     public string GetMember(int IdMember)
     {
         Member m = new Member();//Get Member from DB, exam Linq to Sql
         m.Surname = "Smith";
         m.FirstName = "John";
         return string.Format("{{ \"Surname\":\"{0}\",\"FirstName\":\"{1}\" }}",m.Surname,m.FirstName);
     }
}

---- Default.aspx ----

<a href="#" id="button1">Just a test</a>
<script type="text/javascript">
    $("#button1").click(function (event) {
        event.preventDefault();
        $.ajax({
            type: "POST",
            url: "WSMember.asmx/GetMember",
            data: "{IdMember: 2 }",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (msg) {
                if (msg.hasOwnProperty('d')) {
                    msg = msg.d;
                }
                var json = JSON.parse(msg);
                console.log(json.Surname);
                console.log(json.FirstName);
            },
            error: function (xhr, status, error) {
                //console.log(xhr);
                //console.log(status);
                //console.log(error);
            }
        });
    });
</script>
...