Подтвердить что ты не робот

Принуждение веб-службы ASP.net для возврата JSON

У меня есть веб-служба ASP.net, которую я использую для веб-приложения, которое возвращает мне данные XML или JSON, в зависимости от функции, которую я вызываю. Пока это работает, но я столкнулся с проблемой. Я хочу создать ссылку "экспорт" на моей странице, которая загрузит файл JSON. Ссылка очень проста:

<a href="mywebserviceaddress/ExportFunc?itemId=2">Export This Item</a>

Как вы можете себе представить, это должно экспортировать элемент 2. До сих пор так хорошо, да?

Проблема заключается в том, что, поскольку я специально не запрашиваю, чтобы принятый тип контента был JSON, ASP.net абсолютно отказывается отправлять что-либо, кроме XML, что просто не подходит для этой ситуации. Код по существу выглядит следующим образом:

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public Item ExportItem(int itemId)
    {
        Context.Response.AddHeader("content-disposition", "attachment; filename=export.json"); //Makes it a download

        return GetExportItem(itemId);
    }

Несмотря на то, что я указываю ResponseFormat как JSON, я всегда возвращаю XML, если я не прошу этот метод через AJAX (используя Google Web Toolkit, BTW):

    RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, "mywebserviceaddress/ExportFunc");
    builder.setHeader("Content-type","application/json; charset=utf-8");
    builder.setHeader("Accepts","application/json");
    builder.sendRequest("{\"itemId\":2}", new RequestCallback(){...});

Это здорово, но AJAX не даст мне диалогового окна загрузки. Есть ли способ заставить ASP.net вернуть мне JSON, независимо от того, как запрашиваются данные? Мне кажется, что отсутствие ручного переопределения для этого поведения является грубым контролем проекта.


БЫСТРЫЙ ОТВЕТ:

Во-первых, позвольте мне сказать, что я думаю, что ответ womp, вероятно, лучший способ пойти на долгое время (преобразовать в WCF), но deostroll привел меня к ответу, который я буду использовать в ближайшем будущем. Кроме того, следует отметить, что это, по-видимому, работает прежде всего потому, что я хотел просто загрузить, возможно, не так хорошо работает во всех ситуациях. В любом случае, вот код, который я использовал для получения желаемого результата:

    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public void ExportItem(int itemId)
    {
        Item item = GetExportItem(itemId);            

        JavaScriptSerializer js = new JavaScriptSerializer();
        string str = js.Serialize(item);

        Context.Response.Clear();
        Context.Response.ContentType = "application/json";
        Context.Response.AddHeader("content-disposition", "attachment; filename=export.json");
        Context.Response.AddHeader("content-length", str.Length.ToString());
        Context.Response.Flush();
        Context.Response.Write(str);
    }

Обратите внимание на возвращаемый тип void (это означает, что ваш WDSL будет рядом с бесполезным для этой функции). Возвращение чего-либо заведет ответ, который создается вручную.

4b9b3361

Ответ 1

Вот два форума для вашей справки:

http://forums.asp.net/t/1118828.aspx

http://forums.asp.net/p/1054378/2338982.aspx#2338982

У меня нет четкой идеи. Они говорят, сосредоточившись на настройке типа контента для приложения /json. Я раньше не работал с wcf, но думаю, вы можете использовать объект Response.

Задайте тип содержимого объекта ответа. Сделайте response.write, передавая ваши данные json в виде строки, а затем выполните response.end.

Ответ 2

Веб-службы Asp.net - это веб-службы на основе SOAP. Они всегда будут возвращать XML. Библиотеки Ajax пришли, и материал ScriptMethod был введен, но он не меняет базовую концепцию.

Есть несколько вещей, которые вы можете сделать.

WebMethods являются устаревшими с введением WCF. Вы можете рассмотреть перенос ваших веб-сервисов в WCF, в котором вы будете иметь гораздо больший контроль над выходным форматом.

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

Ответ 3

Просто подумал, что я выброшу это, потому что он не упоминался ранее... если вы используете WebServices с ASP.NET 3.5, JSON - это формат возврата по умолчанию. Он также поставляется вместе с сериализатором JSON, поэтому вы можете прекратить использование JavascriptSerializer.

В этой статье в блоге Rick Strahl говорится о строго типизированном преобразовании, которое вы можете выполнять между серверными классами и объектами JSON от клиента.

Недавно я завершил проект с использованием этого нового материала JSON в .NET 3.5, и я очень впечатлен производительностью. Может быть, стоит посмотреть...