web-dev-qa-db-fra.com

Comment renvoyer un JSON propre à partir d'un service WCF?

J'essaie de renvoyer des fichiers JSON à partir d'un service WCF. Ce service renvoie simplement du contenu de ma base de données. Je peux obtenir les données. Cependant, je suis préoccupé par le format de mon JSON. Actuellement, le JSON renvoyé est formaté comme suit:

{"d":"[{\"Age\":35,\"FirstName\":\"Peyton\",\"LastName\":\"Manning\"},{\"Age\":31,\"FirstName\":\"Drew\",\"LastName\":\"Brees\"},{\"Age\":29,\"FirstName\":\"Tony\",\"LastName\":\"Romo\"}]"} 

En réalité, je voudrais que mon JSON soit formaté aussi proprement que possible. Je pense (je me trompe peut-être) que la même collection de résultats, représentée dans un JSON propre, devrait ressembler à ceci:

[{"Age":35,"FirstName":"Peyton","LastName":"Manning"},{"Age":31,"FirstName":"Drew","LastName":"Brees"},{"Age":29,"FirstName":"Tony","LastName":"Romo"}]

Je ne sais pas d'où vient le "d". Je ne sais pas non plus pourquoi les caractères d'échappement sont insérés. Mon entité ressemble à ceci:

[DataContract]
public class Person
{
    [DataMember]
    public string FirstName { get; set; }

    [DataMember]
    public string LastName { get; set; }

    [DataMember]
    public int Age { get; set; }

    public Person(string firstName, string lastName, int age)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
        this.Age = age;
    }
}

Le service responsable du renvoi du contenu est défini comme suit:

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TestService
{
    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json)]
    public string GetResults()
    {
        List<Person> results = new List<Person>();
        results.Add(new Person("Peyton", "Manning", 35));
        results.Add(new Person("Drew", "Brees", 31));
        results.Add(new Person("Tony", "Romo", 29));

        // Serialize the results as JSON
        DataContractJsonSerializer serializer = new DataContractJsonSerializer(results.GetType());
        MemoryStream memoryStream = new MemoryStream();
        serializer.WriteObject(memoryStream, results);

        // Return the results serialized as JSON
        string json = Encoding.Default.GetString(memoryStream.ToArray());
        return json;
    }
}

Comment renvoyer un JSON "propre" à partir d'un service WCF? Je vous remercie!

228
user208662

Changez le type de retour de vos GetResults en List<Person>.
Supprimez le code que vous utilisez pour sérialiser la liste en une chaîne json - WCF le fait automatiquement.

En utilisant votre définition pour la classe Person, ce code fonctionne pour moi:

public List<Person> GetPlayers()
{
    List<Person> players = new List<Person>();
    players.Add(new  Person { FirstName="Peyton", LastName="Manning", Age=35 } );
    players.Add(new  Person { FirstName="Drew", LastName="Brees", Age=31 } );
    players.Add(new  Person { FirstName="Brett", LastName="Favre", Age=58 } );

    return players;
}

résultats:

[{"Age":35,"FirstName":"Peyton","LastName":"Manning"},  
 {"Age":31,"FirstName":"Drew","LastName":"Brees"},  
 {"Age":58,"FirstName":"Brett","LastName":"Favre"}]

(Sur une seule ligne)

J'ai aussi utilisé cet attribut sur la méthode:

[WebInvoke(Method = "GET",
           RequestFormat = WebMessageFormat.Json,
           ResponseFormat = WebMessageFormat.Json,
           UriTemplate = "players")]

WebInvoke avec Method = "GET" est identique à WebGet, mais comme certaines de mes méthodes sont POST, j'utilise tout WebInvoke pour la cohérence.

UriTemplate définit l'URL à laquelle la méthode est disponible. Je peux donc faire un GET sur http://myserver/myvdir/JsonService.svc/players et cela fonctionne.

Consultez également IIRF ou un autre enregistreur d’URL pour vous débarrasser du fichier .svc de l’URI.

211
Cheeso

Si vous voulez Nice json sans attribut de codage en dur dans vos classes de service,

utilisez <webHttp defaultOutgoingResponseFormat="Json"/> dans votre configuration de comportement

90
JeremyWeir

Ceci est accompli dans web.config pour votre webservice. Définissez bindingBehavior sur <webHttp> et vous verrez le JSON vierge. Le "[d]" supplémentaire est défini par le comportement par défaut que vous devez remplacer.

Voir en outre cet article de blog: http://blog.clauskonrad.net/2010/11/how-to-expose-json-endpoint-from-wcf.html

28
user517301

J'ai rencontré le même problème et je l'ai résolu en modifiant l'attribut BodyStyle en "WebMessageBodyStyle.Bare":

[OperationContract]
[WebGet(BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json, UriTemplate = "GetProjectWithGeocodings/{projectId}")]
GeoCod_Project GetProjectWithGeocodings(string projectId);

L'objet retourné ne sera plus emballé.

7
KhalilG

Lorsque vous utilisez la méthode GET, le contrat doit être le suivant.

[WebGet(UriTemplate = "/", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
List<User> Get();

avec cela, nous avons un json sans le paramètre de démarrage

Aldo Flores @alduar http://alduar.blogspot.com

1
alduar

Dans votre IServece.cs, ajoutez la balise suivante: BodyStyle = WebMessageBodyStyle.Bare

 [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "Getperson/{id}")]

    List<personClass> Getperson(string id);
0
Osama Ibrahim