web-dev-qa-db-fra.com

service web asp.net asmx renvoyant xml au lieu de json

Pourquoi ce simple service Web refuse-t-il de renvoyer JSON au client?

Voici mon code client:

        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);
            }
        });

Et le service:

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>

Et la réponse:

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://tempuri.org/">Hello World</string>

Quoi que je fasse, la réponse revient toujours en XML. Comment puis-je obtenir le service Web pour retourner Json?

MODIFIER:

Voici la trace HTTP de 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>

J'ai perdu le compte du nombre d'articles que j'ai lus maintenant en essayant de résoudre ce problème. Les instructions sont soit incomplètes, soit ne résolvent pas mon problème pour une raison quelconque. Quelques-unes des plus pertinentes incluent (toutes sans succès):

Plus plusieurs autres articles généraux.

49
njr101

Enfin compris.

Le code de l'application est correct tel que publié. Le problème est avec la configuration. Le bon web.config est:

<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>

Selon la documentation, l'enregistrement du gestionnaire devrait être inutile à partir de .NET 4 car il a été déplacé vers le fichier machine.config. Pour une raison quelconque, cela ne fonctionne pas pour moi. Mais l'ajout de l'enregistrement au web.config pour mon application a résolu le problème.

Un grand nombre d'articles sur ce problème demandent d'ajouter le gestionnaire à la section <system.web>. Cela ne fonctionne pas et provoque beaucoup d'autres problèmes. J'ai essayé d'ajouter le gestionnaire aux deux sections, ce qui génère un ensemble d'autres erreurs de migration qui ont complètement mal orienté mon dépannage.

Au cas où cela aiderait quelqu'un d'autre, si j'avais à nouveau le même problème, voici la liste de contrôle que je passerais en revue:

  1. Avez-vous spécifié type: "POST" dans la demande ajax?
  2. Avez-vous spécifié contentType: "application/json; charset=utf-8" dans la demande ajax?
  3. Avez-vous spécifié dataType: "json"dans la demande ajax?
  4. Votre service Web .asmx inclut-il l'attribut [ScriptService]?
  5. Votre méthode Web inclut-elle l'attribut [ScriptMethod(ResponseFormat = ResponseFormat.Json)] ? (Mon code fonctionne même sans cet attribut, mais beaucoup d'articles disent qu'il est requis)
  6. Avez-vous ajouté la ScriptHandlerFactory au fichier web.config dans <system.webServer><handlers>?
  7. Avez-vous supprimé tous les gestionnaires du fichier web.config dans <system.web><httpHandlers>?

J'espère que cela aide quelqu'un avec le même problème. et merci aux affiches pour des suggestions.

44
njr101

Pas de succès avec la solution ci-dessus, voici comment je l'ai résolue.

mettez cette ligne dans votre service Web et renvoyez plutôt le type, écrivez simplement la chaîne dans le contexte de la réponse

this.Context.Response.ContentType = "application/json; charset=utf-8";
this.Context.Response.Write(serial.Serialize(city));
24
Ajay

Si vous souhaitez rester avec Framework 3.5, vous devez modifier le code comme suit.

[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);
    }
}
12
Kalpesh Desai

Il existe un moyen beaucoup plus simple de renvoyer une chaîne pure à partir d'un service Web. J'appelle cela la fonction CROW (le rend facile à retenir). 

  [WebMethod]
  public void Test()
    {
        Context.Response.Output.Write("and that's how it's done");    
    }

Comme vous pouvez le constater, le type de retour est "void", mais la fonction CROW renverra toujours la valeur souhaitée.

6
GabrielJ

J'ai un service Web .asmx (.NET 4.0) avec une méthode qui renvoie une chaîne. La chaîne est une liste sérialisée comme vous le voyez dans beaucoup d'exemples. Cela renverra un JSON qui n'est pas encapsulé dans XML. Aucune modification de web.config ou besoin de DLL tierces.

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 partie client qui utilise le service ressemble à ceci:

   $.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);
       }
   });
1
smoore4

J'espère que cela vous aidera, il apparaît que vous devez toujours envoyer un objet JSON dans la demande, même si la méthode que vous appelez ne contient aucun paramètre.

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;
    });
0
Otto

Pour moi, cela fonctionne avec ce code que j'ai reçu de ce post:

Comment puis-je retourner JSON à partir de mon service de repos WCF (.NET 4), en utilisant Json.Net, sans qu'il s'agisse d'une chaîne, entourée de guillemets?

[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);
}
0
j0aqu1n

Je sais que c’est une question très ancienne, mais j’ai eu le même problème aujourd’hui et j’ai cherché partout pour trouver la réponse, mais sans résultat. Après de longues recherches, j'ai trouvé le moyen de faire ce travail. Pour renvoyer JSON du service, vous devez fournir les données dans la requête dans le format correct. Utilisez JSON.stringify() pour analyser les données avant la requête, sans oublier le contentType: "application/json; charset=utf-8".

0
Sebastian Siewień

J'ai essayé toutes les étapes ci-dessus (même la réponse), mais je n'ai pas réussi. Ma configuration système est Windows Server 2012 R2, IIS 8. L'étape suivante a résolu mon problème.

Changement du pool d'applications, qui a géré pipeline = classic.

0
Arindam Nayak