Asp.net asmx веб-сервис возвращает xml вместо json
Почему этот простой веб-сервис отказывается возвращать JSON клиенту?
Вот мой код клиента:
var params = { };
$.ajax({
url: "/Services/SessionServices.asmx/HelloWorld",
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
timeout: 10000,
data: JSON.stringify(params),
success: function (response) {
console.log(response);
}
});
И служба:
namespace myproject.frontend.Services
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[ScriptService]
public class SessionServices : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string HelloWorld()
{
return "Hello World";
}
}
}
web.config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
</configuration>
И ответ:
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World</string>
Независимо от того, что я делаю, ответ всегда возвращается как XML. Как заставить веб-службу вернуть Json?
EDIT:
Вот трассировка HTTP Fiddler:
REQUEST
-------
POST http://myproject.local/Services/SessionServices.asmx/HelloWorld HTTP/1.1
Host: myproject.local
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0.1
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-gb,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/json; charset=utf-8
X-Requested-With: XMLHttpRequest
Referer: http://myproject.local/Pages/Test.aspx
Content-Length: 2
Cookie: ASP.NET_SessionId=5tvpx1ph1uiie2o1c5wzx0bz
Pragma: no-cache
Cache-Control: no-cache
{}
RESPONSE
-------
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Tue, 19 Jun 2012 16:33:40 GMT
Content-Length: 96
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World</string>
Я потерял количество статей, которые я прочитал, пытаясь исправить это. Инструкции либо неполные, либо не разрешают мою проблему по какой-либо причине.
Некоторые из наиболее важных включают (все без успеха):
Плюс несколько других общих статей.
Ответы
Ответ 1
Наконец понял.
Код приложения правильный, как указано. Проблема заключается в конфигурации. Правильный файл web.config:
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.webServer>
<handlers>
<add name="ScriptHandlerFactory"
verb="*" path="*.asmx"
type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
resourceType="Unspecified" />
</handlers>
</system.webServer>
</configuration>
Согласно документам, регистрация обработчика должна быть ненужной с .NET 4 вверх, поскольку она была перенесена в файл machine.config. По какой-то причине это не работает для меня. Но добавление регистрации в web.config для моего приложения устраняет проблему.
В большинстве статей этой проблемы добавьте обработчик в раздел <system.web>
. Это НЕ работает и вызывает целый ряд других проблем. Я попытался добавить обработчик к обоим разделам, и это порождает множество других ошибок переноса, которые полностью неверно направили мое устранение неполадок.
В случае, если это поможет кому-то еще, если у меня снова будет такая же проблема, вот контрольный список, который я бы рассмотрел:
- Вы указали
type: "POST"
в запросе ajax?
- Вы указали
contentType: "application/json; charset=utf-8"
в запросе ajax?
- Вы указали
dataType: "json"
в запросе ajax?
- Включает ли ваш веб-сервис .asmx атрибут
[ScriptService]
?
- Использует ли ваш веб-метод атрибут
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
? (Мой код работает даже без этого атрибута, но многие статьи говорят, что это требуется)
- Добавили ли вы
ScriptHandlerFactory
в файл web.config в <system.webServer><handlers>
?
- Удалили ли вы все обработчики из файла web.config в
<system.web><httpHandlers>
?
Надеюсь, это поможет любому, у кого есть такая же проблема. и благодаря плакатам для предложений.
Ответ 2
Нет успеха в решении выше, вот как я его разрешил.
поместите эту строку в свой веб-сервис и скорее верните тип, просто напишите строку в контексте ответа
this.Context.Response.ContentType = "application/json; charset=utf-8";
this.Context.Response.Write(serial.Serialize(city));
Ответ 3
Если вы хотите остаться в Framework 3.5, вам необходимо внести изменения в код следующим образом.
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[ScriptService]
public class WebService : System.Web.Services.WebService
{
public WebService()
{
}
[WebMethod]
public void HelloWorld() // It IMP to keep return type void.
{
string strResult = "Hello World";
object objResultD = new { d = strResult }; // To make result similarly like ASP.Net Web Service in JSON form. You can skip if it not needed in this form.
System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();
string strResponse = ser.Serialize(objResultD);
string strCallback = Context.Request.QueryString["callback"]; // Get callback method name. e.g. jQuery17019982320107502116_1378635607531
strResponse = strCallback + "(" + strResponse + ")"; // e.g. jQuery17019982320107502116_1378635607531(....)
Context.Response.Clear();
Context.Response.ContentType = "application/json";
Context.Response.AddHeader("content-length", strResponse.Length.ToString());
Context.Response.Flush();
Context.Response.Write(strResponse);
}
}
Ответ 4
Существует гораздо более простой способ вернуть чистую строку из веб-службы. Я называю его функцией CROW (упрощает запоминание).
[WebMethod]
public void Test()
{
Context.Response.Output.Write("and that how it done");
}
Как вы можете видеть, тип возврата является "void", но функция CROW по-прежнему возвращает требуемое значение.
Ответ 5
У меня есть веб-служба .asmx(.NET 4.0) с методом, который возвращает строку. Строка представляет собой сериализованный Список, как вы видите во многих примерах. Это вернет json, который не завернут в XML. Нет изменений в web.config или для сторонних DLL.
var tmsd = new List<TmsData>();
foreach (DataRow dr in dt.Rows)
{
m_firstname = dr["FirstName"].ToString();
m_lastname = dr["LastName"].ToString();
tmsd.Add(new TmsData() { FirstName = m_firstname, LastName = m_lastname} );
}
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string m_json = serializer.Serialize(tmsd);
return m_json;
Клиентская часть, использующая службу, выглядит следующим образом:
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
dataType: 'json',
url: 'http://localhost:54253/TmsWebService.asmx/GetTombstoneDataJson',
data: "{'ObjectNumber':'105.1996'}",
success: function (data) {
alert(data.d);
},
error: function (a) {
alert(a.responseText);
}
});
Ответ 6
Для меня это работает с этим кодом, который я получил из этого сообщения:
Как я могу вернуть json из моего сервиса WCF rest (.NET 4), используя Json.Net, не будучи строкой, заключенной в кавычки?
[WebInvoke(UriTemplate = "HelloWorld", Method = "GET"), OperationContract]
public Message HelloWorld()
{
string jsonResponse = //Get JSON string here
return WebOperationContext.Current.CreateTextResponse(jsonResponse, "application/json; charset=utf-8", Encoding.UTF8);
}
Ответ 7
Я пробовал все вышеперечисленные шаги (даже ответ), но я не был успешным, моя конфигурация системы - Windows Server 2012 R2, IIS 8. Следующий шаг решил мою проблему.
Изменен пул приложений, который имеет управляемый трубопровод = классический.
Ответ 8
Я знаю, что это действительно старый вопрос, но сегодня я пришел к той же проблеме, и я искал везде, чтобы найти ответ, но без результата. После долгих исследований я нашел способ сделать эту работу. Чтобы вернуть JSON из службы, вы предоставили данные в запросе в правильном формате, используйте JSON.stringify()
для анализа данных перед запросом и не забывайте о contentType: "application/json; charset=utf-8"
, используя это, чтобы обеспечить ожидаемый результат.
Ответ 9
Надеемся, что это поможет, похоже, что вам все равно придется отправить некоторый объект JSON в запрос, даже если метод, который вы вызываете, не имеет параметров.
var params = {};
return $http({
method: 'POST',
async: false,
url: 'service.asmx/ParameterlessMethod',
data: JSON.stringify(params),
contentType: 'application/json; charset=utf-8',
dataType: 'json'
}).then(function (response) {
var robj = JSON.parse(response.data.d);
return robj;
});
Ответ 10
response = await client.GetAsync(RequestUrl, HttpCompletionOption.ResponseContentRead);
if (response.IsSuccessStatusCode)
{
_data = await response.Content.ReadAsStringAsync();
try
{
XmlDocument _doc = new XmlDocument();
_doc.LoadXml(_data);
return Request.CreateResponse(HttpStatusCode.OK, JObject.Parse(_doc.InnerText));
}
catch (Exception jex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, jex.Message);
}
}
else
return Task.FromResult<HttpResponseMessage>(Request.CreateResponse(HttpStatusCode.NotFound)).Result;