2008-10-13 5 views
17

J'ai un objet proxy généré par Visual Studio (côté client) nommé ServerClient. Je cherche à mettre ClientCredentials.UserName.UserName/mot de passe avant d'ouvrir une nouvelle connexion en utilisant ce code:L'erreur "Object is read only" s'affiche lors de la définition de ClientCredentials dans WCF

InstanceContext context = new InstanceContext(this); 

m_client = new ServerClient(context); 
m_client.ClientCredentials.UserName.UserName = "Sample"; 

Dès que le code HITS la ligne UserName il échoue avec un « objet est en lecture seule » erreur . Je sais que cela peut arriver si la connexion est déjà ouverte ou en panne, mais à ce stade je n'ai pas encore appelé context.Open().

J'ai configuré les liaisons (qui utilise netTcpBinding) pour utiliser Message comme mode de sécurité, et MessageClientCredentialType est défini sur UserName.

Des idées?

Répondre

8

Il semble que vous ne puissiez accéder à ces propriétés que très tôt dans le cycle d'instanciation. Si je surcharger le constructeur dans la classe proxy (ServerClient), je suis en mesure de définir ces propriétés:

base.ClientCredentials.UserName.UserName = "Sample"; 

Je commence à apprécier les gens qui n'utilisent pas les suggèrent procurations automatiquement construit fournies par VS.

+0

La seule raison pour laquelle j'utilise le proxy de Microsoft est parce qu'il génère automatiquement des méthodes Async .. –

0

Je pense que votre problème peut être lié à l'utilisation de InstanceContext. Je pensais que c'était seulement nécessaire pour les canaux de communication duplex du côté du serveur. J'avoue que je ne suis pas sûr à ce sujet, mais je pense que dans ce cas, vous dites au client d'utiliser un contexte d'instance existant afin qu'il pense qu'il existe déjà un service en cours d'exécution et qu'il n'autorise pas les modifications.

Qu'est-ce qui motive l'utilisation de InstanceContext?

1

J'ai un code similaire qui est passe UserName bien:

FooServiceClient client = new FooServiceClient("BasicHttpBinding_IFooService"); 
    client.ClientCredentials.UserName.UserName = "user"; 
    client.ClientCredentials.UserName.Password = "password"; 

Essayez de créer le proxy avec le nom obligatoire dans app.config.

5

ici est le colution:

using SysSvcmod = System.ServiceModel.Description; 

SysSvcmod.ClientCredentials clientCredentials = new SysSvcmod.ClientCredentials(); 
clientCredentials.UserName.UserName = "user_name"; 
clientCredentials.UserName.Password = "pass_word"; 

m_client.ChannelFactory.Endpoint.Behaviors.RemoveAt(1); 
m_client.ChannelFactory.Endpoint.Behaviors.Add(clientCredentials); 
0

Si vous utilisez un client duplex, lorsque vous instanciez le DuplexChannelFactory dans le DuplexClientBase que votre client est dérivé est initialisé avec les informations d'identification existantes afin qu'il puisse ouvrir le canal de rappel, ce qui explique pourquoi les informations d'identification seraient en lecture seule.

Je seconde la question de Mike et demande également pourquoi utilisez-vous NetTcpBinding si vous n'utilisez pas sa sécurité de niveau de transport inhérente? Peut-être une liaison basée sur HTTP serait un meilleur ajustement? Cela vous permettrait d'utiliser la sécurité basée sur le certificat qui, je crois, peut être modifiée après l'instanciation (http://msdn.microsoft.com/en-us/library/ms576164.aspx).

0

Un tir dans le noir mais netTcpBinding permet la validation du nom d'utilisateur et du mot de passe? Essayez d'utiliser la sécurité de la couche application (SOAP) à l'aide d'une liaison http

12

J'ai remarqué qu'après avoir créé une instance de la classe proxy pour le service, je peux définir le nom d'utilisateur et le mot de passe une fois sans erreur et effectuer un appel réussi vers mon service web. Lorsque j'essaie ensuite de redéfinir le nom d'utilisateur et le mot de passe sur l'instance existante (inutile bien sûr), j'obtiens l'erreur 'Object is Read-Only' que vous avez mentionnée. La définition des valeurs une fois par instance a fonctionné pour moi.

+0

plus appropriée, les informations d'identification doivent être mis en avant toute méthode de service est appelé. tenter de définir des informations d'identification après avoir appelé une méthode donne une erreur - les informations d'identification ont été définies implicitement lorsque vous avez effectué l'appel de service et ne peuvent pas être modifiées maintenant; ils sont immuables. – morpheus

+0

Dans mon cas, même quelque chose d'aussi inoffensif que l'ajout d'un gestionnaire d'événement à l'objet client (et rien d'autre) a provoqué la propriété en lecture seule. – Nuzzolilo

0

La syntaxe correcte est:

// Supprimer le comportement de ClientCredentials. client.ChannelFactory.Endpoint.Behaviors.Remove <ClientCredentials>();

// Ajout d'une instance d'informations d'identification client personnalisée à la collection de comportements. client.ChannelFactory.Endpoint.Behaviors.Add (nouveau MyClientCredentials());

http://msdn.microsoft.com/en-us/library/ms730868.aspx

Il a travaillé pour moi.

0

Je faisais face au même problème, mon code a commencé à fonctionner lorsque j'ai changé mon code, c'est-à-dire en affectant des valeurs aux informations d'identification du client immédiatement après l'initialisation de l'objet Client.

ici est la solution,

ProductClient Manager = new ProductClient();  
Manager.ClientCredentials.UserName.UserName = txtUserName.Text; 
Manager.ClientCredentials.UserName.Password = txtPassword.Text; 
Questions connexes