ASP.NET WebService оборачивает мой ответ JSON тегами XML - PullRequest
11 голосов
/ 13 января 2010

Я не уверен, куда я иду не так, как мне не хватает.

Я создаю веб-приложение ASP.NET 2.0 (на платформе .Net 3.5) и включаю веб-сервис. Обратите внимание, что это , а не проект MVC. Я хочу выставить метод, который будет возвращать строку JSON; отформатирован для подачи в плагин jqGrid jQuery.

Это предварительный метод тестирования, который я реализовал в своем сервисе: спасибо ( Руководство Phil Haack для MVC )

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string getData()
{
    JavaScriptSerializer ser = new JavaScriptSerializer();

    var jsonData = new
    {
        total = 1, // we'll implement later 
        page = 1,
        records = 3, // implement later 
        rows = new[]{
          new {id = 1, cell = new[] {"1", "-7", "Is this a good question?", "yay"}},
          new {id = 2, cell = new[] {"2", "15", "Is this a blatant ripoff?", "yay"}},
          new {id = 3, cell = new[] {"3", "23", "Why is the sky blue?", "yay"}}
        }
    };

    return ser.Serialize(jsonData); //products.ToString();
}

При вызове возвращается (отформатировано для ясности):

<?xml version="1.0" encoding="utf-8" ?> 
<string  mlns="http://tempuri.org/">
{
  "total":1,
  "page":1,
  "records":3,
  "rows":
    [
      {"id":1,"cell":["1","-7","Is this a good question?","yay"]},
      {"id":2,"cell":["2","15","Is this a blatant ripoff?","yay"]},
      {"id":3,"cell":["3","23","Why is the sky blue?","yay"]}
    ]
}
</string> 

Как бы я мог получить вышеуказанный ответ без XML-упаковок?

Ответы [ 6 ]

9 голосов
/ 13 января 2010

В вашем коде не «возвращайте» json. Используйте вместо:

Context.Response.Write(ser.Serialize(jsonData));

Тогда тебе будет хорошо.

Обычная команда возврата помогает в более правильном формате обслуживания. Некоторые скажут, что будет лучше использовать это, и разверните ваш json на клиенте из этого формата. Я говорю, просто наплевать на вещи именно так, как вы хотите их использовать!

8 голосов
/ 13 января 2010

Три вещи, которые вы, возможно, не делаете:

  • Маркировка метода статическая
  • Выполнение POST
  • Вручите пустое "{}" для данных в jQuery.

Может быть способ вызвать метод с помощью GET, я когда-либо использовал только POST. Я смог заставить ваш пример работать с этим:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script>
    // In your javascript block
    $(document).ready(function()
    {
        $.ajax({
            url: "/Default.aspx/Tester",
            type: "POST",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            data: "{}",
            success: done
        });
    });

    function done(data)
    {
        // Include http://www.json.org/json2.js if your browser doesn't support JSON natively
        var data = JSON.parse(data.d);
        alert(data.total);
    }
</script>

Код (вам не нужно создавать веб-сервис, вы можете поместить его в default.aspx):

[WebMethod]
public static string Tester()
{
    JavaScriptSerializer ser = new JavaScriptSerializer();

    var jsonData = new
    {
        total = 1, // we'll implement later 
        page = 1,
        records = 3, // implement later 
        rows = new[]{
              new {id = 1, cell = new[] {"1", "-7", "Is this a good question?", "yay"}},
              new {id = 2, cell = new[] {"2", "15", "Is this a blatant ripoff?", "yay"}},
              new {id = 3, cell = new[] {"3", "23", "Why is the sky blue?", "yay"}}
            }
        };

    return ser.Serialize(jsonData); //products.ToString();
}

Результат:

{"d":"{\"total\":1,\"page\":1,\"records\":3,\"rows\":[{\"id\":1,\"cell\":[\"1\",\"-7\",\"Is this a good question?\",\"yay\"]},{\"id\":2,\"cell\":[\"2\",\"15\",\"Is this a blatant ripoff?\",\"yay\"]},{\"id\":3,\"cell\":[\"3\",\"23\",\"Why is the sky blue?\",\"yay\"]}]}"}

Более подробное объяснение: здесь

2 голосов
/ 13 января 2010

Когда вы помечаете сервис как ScriptService, он автоматически обрабатывает сериализацию JSON. Вы не должны вручную сериализовать ответ. См. эту запись переполнения стека для более подробной информации.

1 голос
/ 17 ноября 2014

Мне повезло больше:

[WebMethod]
public static void GetDocuments()
{
    HttpContext.Current.Response.ContentType = "application/json";
    HttpContext.Current.Response.Write(JsonConvert.SerializeObject(repository.GetDocuments()));
    HttpContext.Current.Response.End();
}

Важно правильно установить тип содержимого и записать JSON непосредственно в ответ, а затем завершить ответ, чтобы никакие дополнительные данные не отправлялись для повреждения вашего ответа. Преимущество этой архитектуры в том, что вы можете использовать любой сериализатор, какой захотите, вы не ограничены встроенным сериализатором JSON. В этом случае я использовал Json.NET .

Я понимаю, что это злоупотребление архитектурой (и мне лично не нравится иметь тип возврата void для чего-то, что должно возвращать данные), но это единственный действительно надежный метод, который я нашел.

С другой стороны, вам следует переключиться на WCF или Web API , по причинам, которые Джон Сондерс описывает здесь . В частности, веб-API очень прост в использовании и позволяет согласовывать типы контента между клиентом и сервером.

1 голос
/ 08 октября 2013

Если вы запрашиваете JSON и включаете атрибут [ScriptService], ASP.NET автоматически сериализует ответ на JSON.То, что вы видели XML, предполагает, что одно из этих двух предварительных условий не было выполнено. Предложения по сериализации в JSON вручную неверны , если только вы не хотите использовать другой сериализатор, например Newtonsoft.

Вот простой рабочий пример веб-службы ASMX с поддержкой JSON:

<%@ WebService Language="C#" Class="WebService" %>
using System;
using System.Collections.Generic;
using System.Web.Services;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService {
    [WebMethod]
    public MyClass Example()
    {
        return new MyClass();
    }

    public class MyClass
    {
        public string Message { get { return "Hi"; } }
        public int Number { get { return 123; } }
        public List<string> List { get { return new List<string> { "Item1", "Item2", "Item3" }; } }
    }
}

JavaScript для запроса и обработки ответа (мы просто выведем предупреждение JS с сообщением из MyClass.Message):

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Test</title>
    <script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.4.js" type="text/javascript"></script>  
</head>
<body>
    <script type="text/javascript">
        $.ajax({
            type: "POST",
            url: "WebService.asmx/Example",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            data: "{ }",
            error: function (XMLHttpRequest, textStatus, errorThrown) { alert(langError + " " + textStatus); },
            success: function (msg) {
                alert(msg.d.Message);
            }
        });
    </script>
</body>
</html>

Запрос Http:

POST http://HOST.com/WebService.asmx/Example HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: http://HOST.com/Test.aspx
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Connection: Keep-Alive
Content-Length: 3
Host: HOST.com

{ }

HTTP-ответ:

HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 08 Oct 2013 08:36:12 GMT
Content-Length: 98

{"d":{"__type":"WebService+MyClass","Message":"Hi","Number":123,"List":["Item1","Item2","Item3"]}}

Результат:

"Hi" отображается во всплывающем окне JS.

См. Также:

https://stackoverflow.com/a/16335022/397817

https://stackoverflow.com/a/3839649/397817

0 голосов
/ 16 мая 2019
  1. сделать тип возврата недействительным
  2. положи свой объект на ^ _ ^
[WebMethod]
public static void GetDocuments()
{
    HttpContext.Current.Response.ContentType = "application/json";
    HttpContext.Current.Response.Write(JsonConvert.SerializeObject( ^_^ ));
    HttpContext.Current.Response.End();
}
...