Веб-сервис ASMX не возвращает JSON, может только POST с использованием application / x-www-form-urlencoded contentType

Я могу вызвать свой веб-сервис с помощью jQuery, ЕСЛИ contentType = "application / x-www-form-urlencoded; charset = utf-8"

Однако это вернет xml: <string>[myjson]</string>

Если я попытаюсь выполнить POST-запрос в службу с помощью «application / json; charset = utf-8», я получу ошибку 500 с пустыми StackTrace и ExceptionType. Моя функция веб-сервиса никогда не срабатывает, поэтому я не совсем уверен, как отладить эту ситуацию.

Мои методы и классы украшены соответствующими атрибутами и настроены на использование JSON в качестве типа ответа (как и мои файлы wsdl и disco). У меня установлены расширения Ajax и необходимые записи в web.config.

Это на ферме SharePoint, но я не уверен, что это имеет большое значение. Я развернул изменения web.config на всех WFE, а также установил расширения ajax. Сервис снова работает, он просто не принимает ничего, кроме типа контента по умолчанию.

Не уверен, что мне здесь не хватает, ребята ...

мой вызов ajax:

$.ajax({
type: "POST",
url: "/_vti_bin/calendar.asmx/Test",
dataType: "json",
data: "{}",
contentType: "application/json; charset=UTF-8",
success: function(msg){
    alert(msg);
    },
error: function(xhr, msg){ alert(msg + '\n' + xhr.responseText); }
});

Мой класс веб-сервиса:

[WebService(Namespace = "http://namespace")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService()]
public class CalendarService : WebService
{
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public string Test()
    {
        return "Hello World";
    }
}

person Steve Ruiz    schedule 22.05.2009    source источник
comment
То же самое происходит в ASP.NET MVC 1.0 при выполнении запроса AJAX.   -  person Eugeniu Torica    schedule 24.09.2010


Ответы (7)


У меня это работает в 2.0 с использованием веб-сервисов, но я установил защиту от .d (см. DataFilter ниже). Я также возвращаю массив объектов. ПРИМЕЧАНИЕ: класс для объекта статичен, или, по крайней мере, у меня он не работал бы правильно.

  $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        data: "{}",
        dataFilter: function(data)
        {
            var msg;
            if (typeof (JSON) !== 'undefined' &&
                typeof (JSON.parse) === 'function')
                msg = JSON.parse(data);
            else
                msg = eval('(' + data + ')');
            if (msg.hasOwnProperty('d'))
                return msg.d;
            else
                return msg;
        },
        url: "webservice/ModifierCodesService.asmx/GetModifierList",
        success: function(msg)
        {
            LoadModifiers(msg);
        },
        failure: function(msg)
        {
            $("#Result").text("Modifiers did not load");
        }
    });

Вот фрагмент моего веб-сервиса:

...

[WebService(Namespace = "http://mynamespace.com/ModifierCodesService/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[ScriptService]
public class ModifierCodesService : System.Web.Services.WebService
{

     /// <summary>
    /// Get a list of Modifiers
    /// </summary>
    /// <returns></returns>
    [WebMethod(EnableSession = true)]
    public Modifier[] GetModifierList()
    {
        return GetModifiers();
    }
       /// <summary>
        /// Modifiers list from database
        /// </summary>
        /// <returns></returns>
        private Modifier[] GetModifiers()
        {
            List<Modifier> modifier = new List<Modifier>();
            ModifierCollection matchingModifiers = ModifierList.GetModifierList();
            foreach (Modifier ModifierRow in matchingModifiers)
            {
                modifier.Add(new Modifier(ModifierRow.ModifierCode, ModifierRow.Description));
            }
            return modifier.ToArray();
        }
    }

...

код объекта:

 public static class ModifierList
    {

        /// <summary>
        /// Returns the Modifier Collection.
        /// </summary>
        /// <param name="prefix"></param>
        /// <returns></returns>
        public static ModifierCollection GetModifierList()
        {
person Mark Schultheiss    schedule 29.09.2009
comment
Итак, нижняя строка измените общедоступную строку Test () {на общедоступную статическую строку Test () {и посмотрите, работает ли это для вас. - person Mark Schultheiss; 29.09.2009

Сегодня я боролся с этим с помощью приложения для iPhone, общающегося с веб-службой .Net.

Я обнаружил, что если я изменил свой Content Type на application / jsonrequest, он прошел без проблем, и я смог обработать данные на моем веб-сервере.

Просто для усмешки я добавил упомянутую выше строку в свой web.config, но она не заставила application / json работать.

person Steve Reed Sr    schedule 29.07.2010

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

основное различие, которое я вижу, - это атрибут класса

[System.Web.Script.Services.ScriptService]

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

       [WebMethod]
       public string TestMethod(){
         return "Testing";
       }

    }

Я должен предположить, что вы используете фреймворк 3.5, потому что это единственный способ раскрыть веб-методы JSON.

Мои вызовы из jQuery выглядят практически одинаково, поэтому проблем нет.

person Bobby Borszich    schedule 23.05.2009

Если вы тестируете это в IE, попробуйте удалить объявление кодировки из атрибута contentType (т.е. оно должно выглядеть так:

contentType: "application/json",

Мне еще предстоит выяснить, почему, но IE, похоже, извращается при выполнении вызовов JSON с частью «charset=UTF-8».

alt text

person Phil.Wheeler    schedule 29.05.2009

Я думаю, вы ищете атрибут WebInvoke или WebGet, он позволяет вам указать шаблон Uri, стиль тела, форматы запроса и ответа, например:

[WebGet(ResponseFormat= WebMessageFormat.Json)]

Эта ссылка может помочь. Есть аналогичная статья для WebInvoke (используется в основном для публикации).

person marr75    schedule 11.06.2009
comment
Вопрос касался веб-сервиса ASMX; WebGet применяется к контрактам WCF. - person Alek Davis; 22.07.2009

Я довольно часто использую вызовы JQuery AJAX JSON для веб-службы ASMX. Он отлично работает во всех браузерах. Я использую .NET 2.0 с установленными расширениями ASP.NET AJAX (в комплекте 3.5).

У моего класса такие же декораторы, как у вашего. В моих методах есть только декоратор [WebMethod(EnableSession = true)]. Однако мой web.config имеет следующую запись в разделе httpHandlers:

<add verb="*" path="*jsonservice.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

Мой вызов jquery выглядит следующим образом:

$.ajax({
    type: "POST",
    contentType: "application/json; charset=utf-8",
    url: "path/to/service/jsonservice.asmx/MethodName",
    data: JSON.stringify(DTO),
    dataType: "json",
    success: function(rtrn) { alert("good"); },
    error: function(req, msg, err) { alert("bad"); }
});

Эта статья корень моих знаний.

person srmark    schedule 17.06.2009

Похоже, вам нужно указать json в качестве формата ответа в теге scriptMethod. Это с vb.net, но я уверен, что вы уловили идею:

ResponseFormat: = ResponseFormat.Json

person ScottE    schedule 25.05.2009
comment
как вы можете видеть во вставленном коде, я предоставляю формат ответа для атрибута ScriptMethod. - person Steve Ruiz; 27.05.2009