Question

Je dois créer un service WCF qui est hébergé dans IIS, utilise http transport et état de maintien dans la mémoire du serveur. Même si je suis conscient que les services ne sont pas stateful une bonne idée, cette dernière contrainte est nécessaire pour faire fonctionner le service avec un client existant.

Ma première pensée a été à la session de asp.net pour stocker les valeurs. J'ai activé le mode de compatibilité asp.net dans mon service, ce qui m'a donné accès aux HttpContext, mais des valeurs qui ont été placés dans l'objet de la session n'étaient pas persisté dans la mémoire. Je suppose que cela est parce que le module http que l'état de session poignées n'a pas été correctement configuré, mais quand googler réponse que je suis tombé, des séances de WCF et pensé qu'il pourrait être une meilleure idée de les utiliser.

Cependant, les sessions WCF semblent ce sous-document et place un ensemble étrange de prerequises sur un service, et je ne l'ai pas été en mesure de trouver une configuration qui convient à mes besoins: doit être hébergé dans IIS, doit utiliser http ou https le transport et ne peut pas répondre à l'authentification windows parce que le client et le serveur ne feront pas partie du même domaine. Je suis en train de faire cela va à l'aide du wsHttpBinding, j'avais entendu des séances de WCF nécessaires soit la sécurité ou d'un message fiable, mais: - Utilisation de la liaison standard et lorsque les serveurs ne font pas partie du même domaine, il échoue avec une exception « SecurityNegotiationException L'appelant n'a pas été authentifié par le service ». Ceci est assez logique car il utilisait la sécurité des fenêtres.

  • Si je désactive toute sécurité, il échoue avec un « contrat exige session, mais Binding « WSHttpBinding » ne supporte pas ou n'est pas correctement configuré pour le soutenir. »

  • Si, tout en maintenant la sécurité désactivé activer un message fiable Je reçois l'exception « de validation de liaison a échoué car le WSHttpBinding ne supporte pas les sessions fiables sur la sécurité des transports (HTTPS). L'usine de canal ou de l'hôte de service n'a pas pu être ouvert. Utiliser la sécurité des messages pour la messagerie sécurisée et fiable sur HTTP. »

  • J'ai essayé d'activer la sécurité au niveau des transports, mais cela ne semble pas faire de différence à l'erreur générée

Y at-il configuration qui pourrait fonctionner pour moi? Ou devrais-je simplement revenir au plan de l'utilisation des sessions de asp.net?

Était-ce utile?

La solution

Vous pouvez avoir WCF informations maintien de session en mémoire dans une jolie façon simple. Pour éliminer toute possible des influences extérieures dans mes instructions, je suppose que vous commencez avec un tout nouveau projet:

  1. Créer un nouveau projet de bibliothèque de service WCF. Ce projet déjà contiendra un service avec une liaison WSHttpBiding préconfiguré.
  2. Aller au contrat de service (IService1.cs) et changer l'attribut ServiceContract à ce qui suit:

    [ServiceContract(SessionMode = SessionMode.Required)]
    
  3. Aller à la implimentation de service (Service1.cs) et ajoutez l'attribut ServiceBehavior suivant à la classe de service (Service1):

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]
    
  4. Ajouter des données de session en tant que membres de la classe de service (Service1):

    public class Service1 : IService1
    {
        ...
    
        private string UserFullName { get; set; }
    
        ...
    }
    
  5. Utilisez les membres à des données spécifiques de la session actuelle (souvenez-vous de les ajouter également au contrat de service, IService1):

    public class Service1 : IService1
    {
        ...
    
        public string Welcome(string fullName)
        {
            UserFullName = fullName ?? "Guest";
            return string.Format("Welcome back, {0}!", UserFullName);
        }
    
        public string Goodbye()
        {
            return string.Format("Come back soon, {0}!", UserFullName ?? "Guest");
        }
    
        ...
    }
    

SessionMode.Required assure que vos clients sont suivis à la session.
InstanceContextMode.PerSession assure qu'une instance de votre classe de service (Service1) est créé pour chaque session, afin que vous puissiez conserver les données de session en elle et il existe dans la mémoire à travers plusieurs appels dans la même session.
ConcurrencyMode.Single assure qu'un seul thread peut entrer dans chaque instance de classe de service (Service1) et de réduire les problèmes possibles de concurrence si vous avez seulement accès aux données de la classe de service (et les emplacements de thread-safe externe).

EDIT: Par défaut, WSHttpBinding ne permet que des sessions de sécurité. Mais il soutient également des sessions fiables, qui permettent l'établissement de sessions sans sécurité activée. La configuration désactive la liaison suivante sécurité et permet à des sessions fiables:

<wsHttpBinding>
    <binding name="wsHttpBindingConfiguration">
        <security mode="None" />
        <reliableSession enabled="true" />
    </binding>
</wsHttpBinding>

Autres conseils

OMI, est ce qui se passe lorsque vous utilisez une technologie avec une mauvaise abstraction sur HTTP comme WCF. Le fait que les services Web WCF pourraient théoriquement être hébergés sans HTTP (ie sur NET TCP, MSMQ, etc) juste rend difficile à utiliser des fonctions intégrées de HTTP sans entrer dans l'enfer de configuration et commencer un jeu de « deviner la configuration correcte par essais et erreurs » où vous essayez chaque permutation de configuration possible jusqu'à ce que vous avez trouvé la bonne qui fonctionne!

En fin de compte, si vous ne pouviez pas utiliser WCF et a dû mettre en œuvre le service Web à partir de zéro vous suffit de définir un cookie lorsque le client authentifié. Puis, avec chaque demande de client saisir simplement les informations de session référencée par ce cookie.

Une solution possible si vous deviez utiliser WCF est de prendre la gestion de session dans vos propres mains (C'est ce que je fais quand je suis satisfait de l'effort nécessaire pour obtenir quelque chose au travail) et ont explicite propriété « session » sur tous vos services Web qui nécessitent une session / authentification (généralement un guid généré sur l'authentification). Ainsi, pour chaque demande ultérieure vous utilisez le guid pour réhydrater les informations de session associée à ce client.

Si vous êtes intéressé à essayer différents cadres de service web, je maintiens un Open Source Web Services Framework qui permet vous construisez configuration libre, sec, services web où testables (sans aucune configuration requise) chaque service Web que vous créez est automatiquement accessible sur REST XML, JSON, JSV, SOAP 1.1, SOAP 1.2 points de terminaison. En effet, il vous permet d'accéder à votre même service Web via une URL HTTP GET pour les clients REST-ful et le débogage facile ainsi que des critères SOAP (un choix populaire encore mandaté par certaines entreprises). Bonjour tout le monde tutoriel devrait vous donner un bon aperçu sur certaines de ses caractéristiques et comment il fonctionne.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top