2010-09-27 5 views
0

Voici un exemple trivial censé renvoyer une chaîne "Hello World". Cependant, un navigateur affiche quelque chose comme SGVsbG8gV29ybGQ=. Quel est le bon moyen de renvoyer un texte en clair à partir d'un service de style oldskul?Obtenir Gibberish au lieu de Hello World à partir d'un service avec webHttpBinding

s'il vous plaît savoir que:

  1. Je ne peux pas retourner une chaîne: trois caractères Unicode seront automatiquement préfixés et le client HTTP héritage ne sera pas en mesure d'interopérer.

  2. Je pourrais retourner un Message, mais je dois quand même garder la fonctionnalité d'analyse pour extraire la variable data. Mélange Message et int types dans la même signature de la méthode n'est pas autorisé AFAIK.

     
    [ServiceContract(SessionMode=SessionMode.NotAllowed)] 
    public interface IHello 
    { 
        [WebGet(UriTemplate = "manager?data={data}")] 
        [OperationContract] 
        Byte[] DoIt(int data); 
    }

    public class Hello : IHello { public Byte[] DoIt(int data) { return Encoding.ASCII.GetBytes("HelloWorld"); } }

UPDATE: It's not gibberish, but correctly encoded response. However, the format is not what I'd expect to receive. I've figured out (as gentlemen below suggest) that the ultimate control of the transport layer messaging format is gained with Message classe. Cependant, si j'en utilise un, je perds la possibilité d'analyser la requête (attribut UriTemplate). Par conséquent, il serait bon de savoir comment intégrer le Message avec UriRequest.

P.S. Si l'intégration "propre" n'est pas possible - quelle est la solution de contournement la plus élégante? Y a-t-il un code derrière le rideau métallique que je peux emprunter et utiliser dans ma mise en œuvre, s'il vous plaît?

Répondre

1

J'ai recherché sur Google une bonne façon de m'intégrer et j'ai constaté que les gens sont bloqués comme je le suis (veuillez me corriger si je me trompe). Jusqu'à présent, la solution suivante fonctionne bien pour moi:

public class Hello : IHello 
    { 
     [WebGet(UriTemplate = "manager")] 
     [OperationContract] 
     Message DoIt(); 
    } 

    public class Hello : IHello 
    { 
     public Message DoIt() 
     { 
      var webContext = WebOperationContext.Current; 
      var request = webContext.IncomingRequest; 
      var queryParameters = request.UriTemplateMatch.QueryParameters; 
      var data = queryParameters["data"]; 

      var result = new StringBuilder(@" 
       <?xml version='1.0'?> 
       ... 
      "); 

      var response = webContext.CreateTextResponse(result.ToString(), "application/xml", Encoding.ASCII); 

      return response; 
     } 
    } 

S'il y a une meilleure alternative - ce serait parfait pour le savoir.

1

Ce n'est pas du charabia - c'est la version codée en base64 des octets ASCII pour "Hello World" (avec un espace). Lorsque vous demandez à un service Web de transmettre des octets, il utilisera base64 ... votre client de service Web effectuera automatiquement le décodage base64 pour récupérer les octets d'origine.

(je ne suggère d'utiliser , vous l'esprit.)

Il est pas clair ce que votre « client HTTP héritage » est, ou ce qu'il attend, nous ne pouvons pas vraiment dire si le retour d'un tableau d'octets est en fait la meilleure réponse ou non.

+0

Merci, alors quelle est la bonne façon de le faire, s'il vous plaît? Est-ce que je creuse la bonne direction? – BreakPhreak

+0

J'ai également vérifié le résultat de ce que GetBytes() renvoie dans le débogueur.Le tableau d'octets est retourné et les valeurs semblent être correctes, comme arr [0] = 72 ('H'), arr [1] = 101 ('e') etc. Il semble que le cadre est mangling avec le résultats. – BreakPhreak

+0

Le code hérité s'attend à recevoir une chaîne de texte brut/XML. Supposons que si "Hello World" est affiché dans le navigateur et que le type de contenu est "text/ascii", alors nous sommes sur la bonne voie. – BreakPhreak

0

La spécification SOAP stipule que les données binaires brutes doivent être codées en base64. Donc, le comportement que vous témoignez est correct.

Si vous devez transmettre des données de caractères ASCII. Vous pouvez utiliser un contrat de message et un message brut.

Message DoIt(DoItRequest request) 

Le message brut créera la réponse contenant des données ASCII. Le contrat de message est utilisé pour récupérer le paramètre int vous avez mentionné:

[MessageContract] 
public class DoItRequest 
{ 
    [MessageBodyMember] public int data; 
} 

Cette page explique comment travailler avec la classe de message.

+0

Merci beaucoup! Je vais lire le lien et je vais l'essayer dès maintenant. Serai-je toujours en mesure de faire analyser ma demande avec UriTemplate? (Je vais essayer pendant ce temps, comme dit, s'il y a des informations pertinentes/pièges - s'il vous plaît être aimable à partager). – BreakPhreak

+0

Juste essayé. L'opération 'DoIt' dans le contrat 'IHello' a un UriTemplate qui attend un paramètre nommé 'data', mais il n'y a pas de paramètre d'entrée avec ce nom dans l'opération. – BreakPhreak