jquery - scraping - scrap webpage c#
jquery ajax call return JSON error de anĂ¡lisis (5)
Aquí, "application/json"
no es un valor válido para la propiedad dataType
. Lo cambié a "json"
en mi proyecto y se resolvió el mismo problema.
Por favor verifique los detalles aquí (comentario # 7): http://bugs.jquery.com/ticket/8216
Estoy usando jquery para llamar a un método wcf ajax que devuelve una lista de objetos como una cadena JSON. La cadena JSON se ve así cuando se inspecciona en fiddler2 (en TextView):
{"d":"[{/"ID/":/"6b2b8c62-31ce-4df2-982b-054ff5f6be72/",/"Name/":/"Carol/",/"Surname/":/"IrishWife/"},{/"ID/":/"d254740a-0a0f-4a1e-9e4f-0812227dd5af/",/"Name/":/"Willie/",/"Surname/":/"Le Roux/"},{/"ID/":/"660bf0dd-436a-4588-a9c0-19fd6fdcee23/",/"Name/":/"Emmas/",/"Surname/":/"Mum/"},{/"ID/":/"6b9403c5-b728-4e96-bcb1-203e7472eec3/",/"Name/":/"Owen/",/"Surname/":/"Lima/"},{/"ID/":/"d52c08fb-4418-4600-960f-243ff4443ee6/",/"Name/":/"Tim/",/"Surname/":/"Lee/"},{/"ID/":/"e2aacf5b-8855-44ce-9338-3d39f8ab3349/",/"Name/":/"Marcello/",/"Surname/":/"MT/"},{/"ID/":/"578be087-8385-46d6-89de-3db31d352cbc/",/"Name/":/"Carlyn/",/"Surname/":/"Homegroup/"},{/"ID/":/"4c805825-2bee-447a-8b75-41ead17db33e/",/"Name/":/"George/",/"Surname/":/"Homegroup/"},{/"ID/":/"ae48804f-5e78-42c8-9ba0-4214c98a5a89/",/"Name/":/"Isla/",/"Surname/":/"Le Roux/"},{/"ID/":/"f8be2f4f-fedb-4863-8a84-44fddea84ea9/",/"Name/":/"Peter/",/"Surname/":/"Anderson/"},{/"ID/":/"15e7644d-ec43-44ff-a959-47e00112da6b/",/"Name/":/"Kitty/",/"Surname/":/"Corbett/"},{/"ID/":/"8fd7fccc-335c-4d5c-93b5-4b00f96a9950/",/"Name/":/"Natalie/",/"Surname/":/"Archibald/"},{/"ID/":/"09b5aad2-2cf1-488a-962b-4d692b05ddea/",/"Name/":/"Miku/",/"Surname/":/"Heally/"},{/"ID/":/"affa369e-5af3-4537-a0f4-71422956da41/",/"Name/":/"Steven/",/"Surname/":/"Corbett/"},{/"ID/":/"65f57da3-4f88-4798-9590-83b4ccecfc44/",/"Name/":/"Tim/",/"Surname/":/"Archibald/"},{/"ID/":/"53bfb451-f66f-4b6e-b430-8d13c95b30d8/",/"Name/":/"Philip/",/"Surname/":/"MT/"},{/"ID/":/"c7f22b9b-4030-4f82-9f75-bbb726cabb73/",/"Name/":/"Vincent/",/"Surname/":/"Van Der Walt/"},{/"ID/":/"232577be-3165-4316-a20d-c2f2a09c5382/",/"Name/":/"Scott/",/"Surname/":/"Lynn/"},{/"ID/":/"913508a1-5dca-4504-8caf-c8e3dc386fc0/",/"Name/":/"Dan/",/"Surname/":/"MT/"},{/"ID/":/"36054a07-b14d-4c1c-b35f-e00875dde7e5/",/"Name/":/"Sarah/",/"Surname/":/"MT/"},{/"ID/":/"f14e7d98-e040-4ba9-928f-f2ff48116b0b/",/"Name/":/"Josh/",/"Surname/":/"IrishDude/"}]"}
Cuando inspecciono el resultado en la vista JSON del fiddler, muestra el siguiente JSON:
d=[{"ID":"6b2b8c62-31ce-4df2-982b-054ff5f6be72","Name":"Carol","Surname":"IrishWife"},{"ID":"d254740a-0a0f-4a1e-9e4f-0812227dd5af","Name":"Willie","Surname":"Le Roux"},{"ID":"660bf0dd-436a-4588-a9c0-19fd6fdcee23","Name":"Emmas","Surname":"Mum"},{"ID":"6b9403c5-b728-4e96-bcb1-203e7472eec3","Name":"Owen","Surname":"Lima"},{"ID":"d52c08fb-4418-4600-960f-243ff4443ee6","Name":"Tim","Surname":"Lee"},{"ID":"e2aacf5b-8855-44ce-9338-3d39f8ab3349","Name":"Marcello","Surname":"MT"},{"ID":"578be087-8385-46d6-89de-3db31d352cbc","Name":"Carlyn","Surname":"Homegroup"},{"ID":"4c805825-2bee-447a-8b75-41ead17db33e","Name":"George","Surname":"Homegroup"},{"ID":"ae48804f-5e78-42c8-9ba0-4214c98a5a89","Name":"Isla","Surname":"Le Roux"},{"ID":"f8be2f4f-fedb-4863-8a84-44fddea84ea9","Name":"Peter","Surname":"Anderson"},{"ID":"15e7644d-ec43-44ff-a959-47e00112da6b","Name":"Kitty","Surname":"Corbett"},{"ID":"8fd7fccc-335c-4d5c-93b5-4b00f96a9950","Name":"Natalie","Surname":"Archibald"},{"ID":"09b5aad2-2cf1-488a-962b-4d692b05ddea","Name":"Miku","Surname":"Heally"},{"ID":"affa369e-5af3-4537-a0f4-71422956da41","Name":"Steven","Surname":"Corbett"},{"ID":"65f57da3-4f88-4798-9590-83b4ccecfc44","Name":"Tim","Surname":"Archibald"},{"ID":"53bfb451-f66f-4b6e-b430-8d13c95b30d8","Name":"Philip","Surname":"MT"},{"ID":"c7f22b9b-4030-4f82-9f75-bbb726cabb73","Name":"Vincent","Surname":"Van Der Walt"},{"ID":"232577be-3165-4316-a20d-c2f2a09c5382","Name":"Scott","Surname":"Lynn"},{"ID":"913508a1-5dca-4504-8caf-c8e3dc386fc0","Name":"Dan","Surname":"MT"},{"ID":"36054a07-b14d-4c1c-b35f-e00875dde7e5","Name":"Sarah","Surname":"MT"},{"ID":"f14e7d98-e040-4ba9-928f-f2ff48116b0b","Name":"Josh","Surname":"IrishDude"}]
Así que fiddler puede analizarlo correctamente, pero en el cliente, la función de devolución de llamada jquery ajax error muestra el siguiente error:
Error: No conversion from text to application/json
El método wcf se define de la siguiente manera:
[OperationContract]
[WebGet(ResponseFormat=WebMessageFormat.Json)]
public string GetPeople(Guid groupId)
{
using (SchedulerContext context = new SchedulerContext())
{
JavaScriptSerializer ser = new JavaScriptSerializer();
var query = from p in context.People
where p.Group_ID == groupId
select new
{
p.ID,
p.Name,
p.Surname
};
return ser.Serialize(query.ToArray());
}
}
Y por último, la llamada jquery es:
$.ajax(
{
type: "GET",
dataType: "application/json",
contentType: "json",
data: { groupId: ''ae09a080-5d7c-4e92-9a87-591574b7c4b8'' },
url: "WebAPI.svc/GetPeople",
error: function (jqXHR, textStatus, errorThrown) {
alert("error");
},
success: function (msg) {
alert(msg.d[0].Name);
}
}
);
¡Gracias por adelantado!
ACTUALIZACIÓN: Gracias a @ user1370958, un paso más cerca de la solución.
Cuando se cambia la función de devolución de llamada de error a la siguiente, se devuelve con éxito el resultado ...
error: function (jqXHR, textStatus, errorThrown) {
var test = $.parseJSON(jqXHR.responseText);
var test2 = $.parseJSON(test.d);
alert(test2[0].Name);
},
No estoy seguro de por qué, pero tengo que analizar el resultado y luego analizar los objetos anidados dentro de ese. Supongo que si alguno de mis tipos devueltos contenía objetos complejos, también habría necesitado otro análisis ...
Con WCF 4.0 , puede agregar un atributo llamado automaticFormatSelectionEnabled
que permite que el servicio vea el encabezado Accept
en la solicitud HTTP para determinar qué formato devolver. Siempre que lo que está devolviendo sea serializable, WCF manejará la serialización correcta para usted. En su llamada jQuery ajax, el encabezado Aceptar se agrega al incluir accepts: {json: "application/json"}
.
He encontrado una solución:
El primer problema fue la excepción de referencia circular en el modelo de entidad. Para superar esto, utilizo el siguiente código para separar mis entidades del contexto y luego serializarlas en cadenas. Luego los serializo en el cliente usando el código debajo de eso.
Servicio
[WebGet(ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
public string[] GetPeople(Guid groupId)
{
using (SchedulerContext context = new SchedulerContext())
{
var people = (from p in context.People
where p.Group_ID == groupId
select p).ToList();
JavaScriptSerializer ser = new JavaScriptSerializer();
string[] result = new string[people.Count];
for (int i = 0; i<people.Count; i++)
{
context.Detach(people[i]);
string json = ser.Serialize(people[i]);
result[i] = json;
}
return result;
}
}
Cliente
$.ajax(
{
type: "GET",
//dataType: "application/json",
//dataType: "text/plain",
contentType: "json",
data: { groupId: ''ae09a080-5d7c-4e92-9a87-591574b7c4b8'' },
//data: { groupId: ''test'' },
//data: { groupId: ''739526F1-7C58-4E3B-97D8-4870948BFE32'' },
url: "WebAPI.svc/GetPeople",
error: function (jqXHR, textStatus, errorThrown) {
alert(jqXHR.resultText);
},
success: function (people) {
//the returned param "people" is of type string[], so each string needs parsed
$(people).each(function (index, value) {
var person = $.parseJSON(value);
//now I can use the Person object
});
}
}
);
Intente agregar el tipo MIME en su código del lado del servidor:
Response.ContentType = "application/json";
Supongo que desea devolver el valor de ser.Serialize(query.ToArray())
al cliente (una matriz). Pero lo está devolviendo como una cadena, por lo que WCF escapará de ese JSON a una cadena, y lo que terminará no es una matriz, sino una cadena.
Dado que está utilizando tipos anónimos, que no son compatibles de forma nativa con WCF, debe usar el JavaScriptSerializer
. Por lo tanto, para evitar la doble codificación de JSON (en la cadena), debe devolver los datos como una transmisión en su lugar, para que WCF no toque sus datos (consulte el código de muestra a continuación).
Una cosa más: veo que su respuesta tiene un envoltorio {"d":...}
, lo que sugiere que está utilizando la <enableWebScript/>
/ WebScriptEnablingBehavior
/ WebScriptServiceHostFactory
al definir su servicio / punto final. Ya que no está utilizando la biblioteca AJAX de ASP.NET, no necesita ese ajuste, por lo que puede usar el <webHttp/>
más simple " <webHttp/>
/ WebHttpBehavior
/ WebServiceHostFactory
, y su respuesta no se ajustará a eso" d "objeto.
[OperationContract]
[WebGet(ResponseFormat = WebMessageFormat.Json)]
public System.IO.Stream GetPeople(Guid groupId)
{
using (SchedulerContext context = new SchedulerContext())
{
JavaScriptSerializer ser = new JavaScriptSerializer();
var query = from p in context.People
where p.Group_ID == groupId
select new
{
p.ID,
p.Name,
p.Surname
};
string json = ser.Serialize(query.ToArray());
using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
return ms;
}
}