Service Web JSONP et ASMX

J’essaie de comprendre comment passer un appel JSONP vers un service Web ASMX à l’aide de jQuery. Voici quelques-unes des pages que j’ai déjà lues et pour lesquelles aucune solution n’a été trouvée:

Comment appeler un service Web externe en utilisant jqueryjsonp“?

Publication de JSON interdomaine dans ASP.NET avec jQuery

Erreur lors de l’access au service Web ASP.net à l’aide de JQuery – JSONP

Définir les en-têtes avec jQuery.ajax et JSONP?

http://www.codeproject.com/Articles/43038/Accessing-Remote-ASP-NET-Web-Services-Using-JSONP

http://encosia.com/using-jquery-to-consume-aspnet-json-web-services/

etc…

Voici mon exemple de méthode Web .NET:

[WebMethod] [ScriptMethod(UseHttpGet = true, ResponseFormat = ResponseFormat.Json)] public void GetEmployee(ssortingng employeeId, ssortingng callback) { // Get the employee object from the Factory. Employee requestedEmployee = EmployeeFactory.GetEmployee(employeeId); if(requestedEmployee != null) { // Return the padded JSON to the caller. CrossDomainUtility.SendJsonP(callback, requestedEmployee.ToJson()); } } 

Voici SendJsonP ():

 public static void SendJsonP(ssortingng callback, ssortingng json) { // Clear any response that has already been prepared. HttpContext.Current.Response.Clear(); // Set the content type to javascript, since we are technically returning Javascript code. HttpContext.Current.Response.ContentType = "application/javascript"; // Create a function call by wrapping the JSON with the callback function name. HttpContext.Current.Response.Write(Ssortingng.Format("{0}({1})", callback, json)); // Complete this request, to prevent the ASMX web service from doing anything else. HttpContext.Current.ApplicationInstance.CompleteRequest(); } 

Et voici un exemple de code jquery:

 $.ajax({ url: 'http://devserver/service/service.asmx/GetEmployee', dataType: 'jsonp', contentType: 'application/json', data: { employeeId: '123456789' } }); 

Le service Web est décoré avec [ScriptService] et mon Web.config est configuré pour gérer * .asmx à l’aide de ScriptHandlerFactory.

J’ai essayé d’utiliser la sérialisation JSON intégrée utilisée par ASMX lorsque Content-Type est ‘application / json’, mais il existe un ou deux problèmes: il ne peut pas fonctionner pour JSONP en raison du remplissage à appliquer au dossier. JSON que .NET ne supporte pas. Cela ne fonctionne pas non plus, car pour sérialiser JSON, ASMX attend un en-tête ‘ContentType: application / json’, mais jQuery ignore les en-têtes ContentType lors de l’envoi de requêtes GET (probablement parce qu’il n’envoie aucun contenu). J’ai essayé de définir Request.ContentType = “application / json” dans Global.asax Application_BeginRequest () mais cela n’a rien fait. J’ai également essayé de définir l’en-tête de la requête dans jQuery en utilisant beforeSend () sans succès.

Donc, comme je ne pouvais pas le faire fonctionner facilement en utilisant le pipeline .NET intégré, j’ai lancé ma propre technique qui effectue des écritures brutes dans le corps de la réponse (d’où la méthode SendJsonP ()). J’ai toujours des problèmes, car même si la méthode Web GetEmployee () ne renvoie pas de valeur, .NET génère des erreurs de sérialisation car il tente de sérialiser l’object en XML car je ne peux pas passer de contenu ContentType of ‘application / json ‘avec les requêtes GET.

Donc, comme jQuery ne peut pas append le ContentType, peu importe ce que je fais, je voulais tester mon service Web en créant simplement des requêtes manuelles à l’aide de Fiddler2:

 GET http://devserver/service/service.asmx/GetEmployee?callback=createMember&memberId=123456789 User-Agent: Fiddler Content-Type: application/json Host: devserver 

… et donne l’erreur suivante car mes parameters ne sont pas JSON:

 {"Message":"Invalid JSON primitive: createMember [....] } 

Donc, après tout cela, je rest avec quelques questions:

  1. Existe-t-il un moyen d’utiliser la sérialisation .NET intégrée pour appliquer un remplissage à JSON et le renvoyer au client?

  2. Puisqu’il semble que je dois rouler le mien, à quoi doit ressembler ma chaîne de requête lors de l’envoi d’une requête JSONP avec des parameters à une page ASMX? Il doit être au format JSON, mais j’ai essayé les solutions suivantes et reçu les erreurs «Invalid JSON primitive»:

    GetEmployee? {Callback: “createMember”, memberId: “99999999”}

    GetEmployee? Callback = {callback: “createMember”} & memberId = {memberId: “123456789”}

  3. Est-il possible que jQuery envoie un en-tête ContentType avec des requêtes JSONP GET?

Je viens de décider de traiter les demandes JSONP manuellement. Dans ma solution, l’utilisateur doit fournir deux parameters de chaîne de requête via une requête GET afin d’indiquer qu’il souhaite obtenir des résultats JSONP: callback = callbackFunctionName et jsonp = true. Si les deux sont reçus, je le traiterai manuellement, sinon la demande continuera sur le processeur ASMX standard.

J’ai créé une nouvelle classe d’assistance JsonPUtility, que j’ai ajoutée en tant qu’appel dans l’événement HttpApplication.BeginRequest:

 public class Global : System.Web.HttpApplication { protected void Application_BeginRequest(object sender, EventArgs e) { // Requests for JSONP requests must be handled manually due to the limitations of JSONP ASMX. JsonPUtility.ProcessJsonPRequest(); } } 

Et voici la classe JsonPUtility:

 /* * JSON is Javascript Object Notation, a standard way of serializing objects in Javascript and * other languages. For more information see http://www.json.org/. * * JSONP is a technique to enable the execution of Javascript that resides in a different domain. It * works by exploiting the exception granted to the  

J'espère que cela pourra aider quelqu'un à l'avenir.

Merci, Vince