web service c# json
El servicio web asp.net asmx devuelve xml en lugar de json (10)
¿Por qué este simple servicio web se niega a devolver JSON al cliente?
Aquí está mi código de cliente:
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);
}
});
Y el servicio:
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>
Y la respuesta:
<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World</string>
No importa lo que haga, la respuesta siempre vuelve como XML. ¿Cómo consigo que el servicio web devuelva a Json?
EDITAR:
Aquí está el seguimiento de Fiddler HTTP:
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>
He perdido la cuenta de cuántos artículos he leído ahora tratando de arreglar esto. Las instrucciones están incompletas o no resuelven mi problema por algún motivo. Algunos de los más relevantes incluyen (todos sin éxito):
- El servicio web ASP.NET devuelve erróneamente XML en lugar de JSON
- El servicio web asmx devuelve xml en lugar de json en .net 4.0
- http://williamsportwebdeveloper.com/cgi/wp/?p=494
- http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/
- http://forums.asp.net/t/1054378.aspx
- http://jqueryplugins.info/2012/02/asp-net-web-service-returning-xml-instead-of-json/
Además de varios otros artículos generales.
Espero que esto ayude, parece que todavía tiene que enviar algún objeto JSON en la solicitud, incluso si el Método al que llama no tiene parámetros.
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;
});
Finalmente lo descubrí.
El código de la aplicación es correcto según lo publicado. El problema es con la configuración. El web.config correcto es:
<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>
De acuerdo con los documentos, el registro del controlador no debería ser necesario desde .NET 4 hacia arriba, ya que se ha movido a machine.config. Por alguna razón, esto no funciona para mí. Pero al agregar el registro a web.config para mi aplicación, se resolvió el problema.
Muchos de los artículos sobre este problema indican agregar el controlador a la sección <system.web>
. Esto NO funciona y causa una carga completa de otros problemas. Traté de agregar el controlador a ambas secciones y esto genera un conjunto de otros errores de migración que dirigieron por completo mi solución de problemas.
En caso de que ayude a alguien más, si volviera a tener el mismo problema, aquí está la lista de verificación que revisaría:
- ¿Especificó el
type: "POST"
en la solicitud de ajax? - ¿Especificó
contentType: "application/json; charset=utf-8"
en la solicitud de AJAX? - ¿Especificó
dataType: "json"
en la solicitud de Ajax? - ¿Su servicio web .asmx incluye el
[ScriptService]
? - ¿Su método web incluye el
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
? (Mi código funciona incluso sin este atributo, pero muchos artículos dicen que es obligatorio) - ¿Ha agregado
ScriptHandlerFactory
al archivo web.config en<system.webServer><handlers>
? - ¿Ha eliminado todos los controladores del archivo web.config en
<system.web><httpHandlers>
?
Espero que esto ayude a cualquiera con el mismo problema. y gracias a los carteles por sugerencias.
Hay una manera mucho más fácil de devolver una cadena pura del servicio web. Lo llamo la función CROW (lo hace fácil de recordar).
[WebMethod]
public void Test()
{
Context.Response.Output.Write("and that''s how it''s done");
}
Como puede ver, el tipo de devolución es "vacío", pero la función CROW seguirá devolviendo el valor que desee.
He intentado todos los pasos anteriores (incluso la respuesta), pero no tuve éxito, la configuración de mi sistema es Windows Server 2012 R2, IIS 8. El siguiente paso resolvió mi problema.
Cambió el grupo de aplicaciones, que ha administrado pipeline = classic.
Ningún éxito con la solución anterior, aquí cómo lo resolví.
ponga esta línea en su servicio web y más bien devuelva escriba simplemente la cadena en contexto de respuesta
this.Context.Response.ContentType = "application/json; charset=utf-8";
this.Context.Response.Write(serial.Serialize(city));
Para mí funciona con este código que obtuve de esta publicación:
[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);
}
Sé que esa es una pregunta muy antigua, pero hoy llegué al mismo problema y he estado buscando en todas partes para encontrar la respuesta, pero sin resultado. Después de una larga investigación, he encontrado la manera de hacer que esto funcione. Para devolver JSON del servicio, debe proporcionar los datos solicitados en el formato correcto, use JSON.stringify()
para analizar los datos antes de la solicitud y no se olvide de contentType: "application/json; charset=utf-8"
, utilizando este debe proporcionar el resultado esperado.
Si desea permanecer, permanezca con Framework 3.5, necesita hacer cambios en el código de la siguiente manera.
[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''s 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''s 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);
}
}
Tengo un servicio web .asmx (.NET 4.0) con un método que devuelve una cadena. La cadena es una lista serializada como la que ve en muchos de los ejemplos. Esto devolverá json que no está envuelto en XML. Sin cambios en web.config o necesidad de archivos DLL de terceros.
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;
La parte del cliente que usa el servicio se ve así:
$.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);
}
});
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;