web-dev-qa-db-fra.com

Retour de json brut (chaîne) dans wcf

Je veux construire mon propre JSON, et que le service retourne une chaîne, voici le code

[OperationContract]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
public string GetCurrentCart()
{
    //Code ommited
    string jsonClient = null;
    var j = new { Content = response.Content, Display=response.Display, SubTotal=response.SubTotal};
    var s = new JavaScriptSerializer();
    jsonClient = s.Serialize(j);
    return jsonClient;
}

La réponse que j'obtiens contient les\"utilisés pour créer" dans les chaînes en c #.

Voici la réponse.

"{\"Content\":\"\\r\\n\\u003cdiv\\u003e\\r\\n\\u003cinput type=\\\"hidden\\\" name=\\\"__VIEWSTATE\\\" id=\\\"__VIEWSTATE\\\" value=\\\"\/wEPDwUBMA9kFgJmD2QWAmYPZBYGAgMPFgIeBFRleHQFKFlvdSBoYXZlIG5vIGl0ZW1zIGluIHlvdXIgc2hvcHBpbmcgY2FydC5kAgUPFgIeB1Zpc2libGVoZAIHDxQrAAIPFgIfAWhkZGQYAQUMY3RsMDEkbHZDYXJ0D2dkoWijqBUJaUxmDgFrkGdWUM0mLpgQmTOe8R8hc8bZco4=\\\" \/\\u003e\\r\\n\\u003c\/div\\u003e\\r\\n\\r\\n\\u003cdiv class=\\\"block block-shoppingcart\\\"\\u003e\\r\\n    \\u003cdiv class=\\\"title\\\"\\u003e\\r\\n        \\u003cspan\\u003eShopping Cart\\u003c\/span\\u003e\\r\\n    \\u003c\/div\\u003e\\r\\n    \\u003cdiv class=\\\"clear\\\"\\u003e\\r\\n    \\u003c\/div\\u003e\\r\\n    \\u003cdiv class=\\\"listbox\\\"\\u003e\\r\\n        You have no items in your shopping cart.\\r\\n        \\r\\n        \\r\\n    \\u003c\/div\\u003e\\r\\n\\u003c\/div\\u003e\\r\\n\",\"Display\":\"You have no items in your shopping cart.\",\"SubTotal\":null}"

Les valeurs sont correctement codées, mais le json lui-même n'est pas correctement formaté. Celles-ci le font se déchaîner.

Comment renvoyer une chaîne sans les\'devant les "?"

47
Paul Knopf

Actuellement, votre méthode Web renvoie un String avec ResponseFormat = WebMessageFormat.Json. Il suit l'encodage JSON de la chaîne. Correspond à www.json.org tous les guillemets doubles dans la chaîne seront échappés en utilisant la barre oblique inverse. Vous disposez donc actuellement d'un double encodage JSON.

Le moyen le plus simple de renvoyer tout type de données consiste à remplacer le type de sortie de la méthode Web GetCurrentCart() par Stream ou Message (de System.ServiceModel.Channels) Au lieu de String.
Voir http://blogs.msdn.com/b/carlosfigueira/archive/2008/04/17/wcf-raw-programming-model-web.aspx , http://msdn.Microsoft.com/en-us/library/ms789010.aspx et http://msdn.Microsoft.com/en-us/library/cc681221 (VS.90) .aspx pour des exemples de code.

Parce que vous n'avez pas écrit dans votre question quelle version de .NET vous utilisez, je vous suggère d'utiliser une manière universelle et la plus simple:

public Stream GetCurrentCart()
{
    //Code ommited
    var j = new { Content = response.Content, Display=response.Display,
                  SubTotal=response.SubTotal};
    var s = new JavaScriptSerializer();
    string jsonClient = s.Serialize(j);
    WebOperationContext.Current.OutgoingResponse.ContentType =
        "application/json; charset=utf-8";
    return new MemoryStream(Encoding.UTF8.GetBytes(jsonClient));
}
109
Oleg

J'ai essayé la méthode suggérée par Oleg mais j'ai découvert que lorsque j'utilisais cette méthode pour une grande quantité de données, la clé nulle Word était ajoutée à la fin de la chaîne JSON.

Exemple: pour json avec beaucoup de données {"JsonExample": "xxxxx"} null

trouvé une solution pour résoudre ce problème à: http://wcf.codeplex.com/workitem/67 A écrit la fonction suivante qui acceptera un objet et renverra une sortie Pure Json. Donc, avant de retourner mon objet dans la méthode principale, j'appelle la méthode ci-dessous.

  public HttpResponseMessage ReturnPureJson(object responseModel)
    {
        HttpResponseMessage response = new HttpResponseMessage();

        string jsonClient = Json.Encode(responseModel);
        byte[] resultBytes = Encoding.UTF8.GetBytes(jsonClient);
        response.Content = new StreamContent(new MemoryStream(resultBytes));
        response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");

        return response;
    }
5
Ivix4u

C'était super (Oleg Response) et assurez-vous tous d'ajouter la ligne WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset = utf-8";

si vous l'avez supprimé, le résultat sera téléchargé sous forme de fichier.

2
Ahmed Samir

Je recommande d'utiliser la bibliothèque Jil pour sérialiser votre objet JSON ou dynamique (ExpandoObject).

Dans mon cas, cela évitera certains problèmes de valeur nulle, comme toujours obtenir "{}" de JsonConvert.SerializeXXX et étendre {aa: bb} à {clé: aa, valeur: bb} à partir de JavaScriptSerializer

échantillon complet ici comme ci-dessous.

Interface:

[OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "json/GetCurrentCart")]
Stream GetCurrentCart(MyRequestParam Param);

Implémentation:

public Stream GetCurrentCart(MyRequestParam Param)
{
    //code omitted
    dynamic j = new System.Dynamic.ExpandoObject();
    j.Content = response.Content;
    j.Display = response.Display; 
    j.SubTotal = response.SubTotal;
    string s = Jil.JSON.SerializeDynamic(j);
    WebOperationContext.Current.OutgoingResponse.ContentType = "application/json; charset=utf-8";
    return new MemoryStream(Encoding.UTF8.GetBytes(s));
} 
2
John_J