У меня есть веб-служба 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 будет практически бесполезен для этой функции). Возврат чего-либо испортит ответ, который создается вручную.