2008-10-13 32 views
17

Tengo un objeto proxy generado por Visual Studio (cliente) llamado ServerClient. Estoy tratando de establecer ClientCredentials.UserName.UserName/contraseña antes de abrir una nueva conexión utilizando este código:Obteniendo el error "El objeto es de solo lectura" al establecer ClientCredentials en WCF

InstanceContext context = new InstanceContext(this); 

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

Tan pronto como el código golpea el Conectado Usuario falla con un "objeto es de sólo lectura" error . Sé que esto puede suceder si la conexión ya está abierta o tiene una falla, pero en este momento aún no he llamado a context.Open().

He configurado los enlaces (que usa netTcpBinding) para usar Message como su modo de seguridad, y MessageClientCredentialType se establece en UserName.

¿Alguna idea?

Respuesta

8

Parece que solo puede acceder a estas propiedades desde el principio del ciclo de instanciación. Si puedo reemplazar el constructor de la clase de proxy (ServerClient), soy capaz de establecer estas propiedades:

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

estoy empezando a apreciar las personas que no sugerir el uso de los proxies construidas de forma automática proporcionados por VS.

+0

La única razón por la que uso de proxy de Microsoft es porque genera automáticamente métodos asincrónicos .. –

0

Creo que su problema podría estar relacionado con el uso de InstanceContext. Pensé que solo era necesario para canales de comunicación dúplex desde el lado del servidor.

Admito que no estoy seguro de esto, pero creo que en este caso le está diciendo al cliente que use un contexto de instancia existente para que piense que ya hay un servicio en ejecución y no permitirá cambios.

¿Qué está impulsando el uso de InstanceContext?

1

que tienen un código similar que está pasando UserName bien:

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

intente crear el proxy con el nombre de unión en app.config.

5

aquí es el 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 se utiliza un cliente dúplex, cuando se instancia que el DuplexChannelFactory dentro del DuplexClientBase que su cliente se deriva de se inicializa con las credenciales existentes para que pueda abrir el canal de devolución de llamada, por eso las credenciales serían solo de lectura.

En segundo lugar pregunto a Mike y también pregunto por qué está utilizando NetTcpBinding si no va a utilizar su seguridad de nivel de transporte inherente? Tal vez un enlace basado en HTTP sería una mejor opción? Eso le permitiría usar la seguridad basada en certificados, que creo que se puede modificar después de la instanciación (http://msdn.microsoft.com/en-us/library/ms576164.aspx).

0

Un tiro en la oscuridad pero netTcpBinding permite la validación de nombre de usuario y contraseña? Intente utilizar la seguridad de la capa de aplicación (SOAP) utilizando un enlace HTTP

12

Me di cuenta de que después de crear una instancia de la clase proxy para el servicio, puedo establecer el nombre de usuario y la contraseña una vez sin errores y hacer una llamada exitosa a mi servicio web. Cuando intento volver a configurar el nombre de usuario y la contraseña en la instancia existente (innecesario por supuesto) aparece el error 'El objeto es de solo lectura' que mencionaste. Establecer los valores una vez por vida de la instancia funcionó para mí.

+0

más apropiadamente, las credenciales es necesario establecer antes de que se llama a cualquier método de servicio. intentar establecer credenciales después de llamar a un método genera un error: las credenciales se establecieron implícitamente cuando realizó la llamada de servicio, y no se pueden cambiar ahora; ellos son inmutables – morpheus

+0

En mi caso, incluso algo tan aparentemente inofensivo como agregar un controlador de eventos al objeto del cliente (y nada más) hizo que la propiedad fuera de solo lectura. – Nuzzolilo

0

La sintaxis correcta es:

// eliminar el comportamiento ClientCredentials. client.ChannelFactory.Endpoint.Behaviors.Remove <ClientCredentials>();

// Agregar una instancia de credenciales de cliente personalizada a la colección de comportamientos. client.ChannelFactory.Endpoint.Behaviors.Add (new MyClientCredentials());

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

que trabajó para mí.

0

Tenía el mismo problema, mi código comenzó a funcionar cuando cambié mi código, es decir, asignaba valores a la credencial del cliente inmediatamente después de inicializar el objeto del cliente.

Aquí está la solución,

ProductClient Manager = new ProductClient();  
Manager.ClientCredentials.UserName.UserName = txtUserName.Text; 
Manager.ClientCredentials.UserName.Password = txtPassword.Text; 
Cuestiones relacionadas