[WCF] Forcer des réponses JSon, même pour des requêtes XML
Par défaut WCF, permets de créer des services REST qui acceptent de fonctionner avec des corps de messages en JSon et en XML. La technologie est assez intelligente pour savoir qu’il faut répondre du XML à un client qui a formulé sa requête en XML et en JSon pour le client qui a communiqué du JSon.
Seul petit hic, par moment on aimerait prendre la main sur le processus et n’autoriser qu’un format d’échange. Si on tente de jouer sur les méthodes de nos services avec les attributs WebInvoke, on se retrouve avec une grosse masse de travail le jour où l’on veut changer d’approche. Et surtout, on ne peut pas être certain de vraiment forcer le service à répondre de la manière attendue (la configuration peut toujours prendre le dessus).
Pour forcer le format des messages, la solution se trouve donc dans la configuration :
<protocolMapping>
<add scheme="http" binding="webHttpBinding" />
</protocolMapping>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp defaultBodyStyle="WrappedRequest"
defaultOutgoingResponseFormat="Json"
automaticFormatSelectionEnabled="false" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Le choix de la réponse est interdit du fait du “false” dans “automaticFormatSelectionEnabled”. Le format du corps de la réponse est fixé par le “defaultOutgoingResponseFormat” qui apour valuer “Json”.
Seul petit hic. Si le client vous interroge en XML, la réponse JSON risque de déstabiliser votre navigateur qui n’acceptera peut-être pas le message ou qui vous ouvrira une boite de dialogue pour vous proposer d’enregistrer la réponse dans un fichier JSon. Heureusement, une solution existe : il faut modifier le ContentType de la réponse pour lui dire qu’il s’agit d’un text (text/plain). Le navigateur n’y verra que du feu et votre client pourra lire la réponse.
En général, les services qui seront concernés seront rares. Il s’agit souvent de services de gestion ou d’upload de fichier. Pour ceux-ci, il suffit d’inclure le code suivant dans les méthodes du service :
WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
Bien sûr, si tous vos services sont concernés, il serait peut-être plus simple d’utiliser ce code dans un behavior WCF.