none
“An element with the same key has already been added” while creating channel from ClientBase RRS feed

  • Pregunta

  • I work with an old and crapy solution written in spanish. We are replacing service references by agents using System.ServiceModel.ClientBase. We have 24 agents for 24 services and with one of them this ArgumentException occurs. The property "ParamName" is null so you can imagine how hard is locate de source of this problem. After a lot of web research, I think the exception is happening because two of this reasons:

     - I have duplicate elements inside system.serviceModel tag, in server's Web.config
     - I have duplicate namespaces in DataContract atrribute, in two or more of the entities included in the knowntypes.

    Otherwise, I am not really sure of that and I know the first reason is not happeing. This is the code of GenericProxy<T>, a child class of ClientBase:

        public class GenericProxy<T> : ClientBase<T> where T : class
        {
            T _channel;

            public GenericProxy(string endpoint)
                : base(endpoint)
            {
            }

            public static ICredencialUsuario Credencial
            {
                set { Configurador.Instancia.Credencial = value; }
            }

            protected override T CreateChannel()
            {
                try
                {
                    if (Configurador.Instancia.Credencial == null)
                    {
                        if (ChannelFactory.Credentials != null) ChannelFactory.Credentials.UserName.UserName = "dummy";
                    }
                    else
                    {
                        if (ChannelFactory.Credentials != null)
                        {
                            ChannelFactory.Credentials.UserName.UserName = Configurador.Instancia.Credencial.Usuario;
                            ChannelFactory.Credentials.UserName.Password = Configurador.Instancia.Credencial.Clave;
                        }
                    }

                    _channel = base.CreateChannel();

                    return _channel;
                }
                catch (Exception ex)
                {
                    throw new Exception("Error al crear el canal de comunicaciones del GenericProxy.", ex);
                }
            }

            public T Proxy
            {
                get { return Channel; }
            }

            public void InvocarOperacion(Action<T> action)
            {
                InvocarOperacion(action, false); //invocacion no asincrona
            }

            public void InvocarOperacionAsincrona(Action<T> action)
            {
                InvocarOperacion(action, true); //invocacion asincrona
            }
            
            private void InvocarOperacion(Action<T> action, bool asincrono)
            {

                T client = CreateChannel();

                try
                {
                    DateTime comienzo = DateTime.Now;
                    action(client);

                    ClientCredentials clientCredentials = ChannelFactory.Credentials;
                    if (clientCredentials != null)
                        Log.logDebug("GenericProxy", String.Format("Usuario {2} y Metodo {3} : Comienzo {0} Fin {1}", comienzo.ToString("HH:mm:ss-ffff"), DateTime.Now.ToString("HH:mm:ss-ffff"),
                            clientCredentials.UserName.UserName,
                            action.Method.Name));

                    //si la petición no es asincrona se cierra el canal
                    if (!asincrono)
                    {
                        ((IClientChannel)client).Close();
                    }
                }
                catch (MessageSecurityException mex)
                {
                    ((IClientChannel)client).Abort();
                    //si no hay un usuario valido, ha habido un fallo durante el proceso de validación, por lo que no se puede continuar
                    if ((Configurador.Instancia.Credencial == null) || (Configurador.Instancia.Credencial.Usuario == null) || (Configurador.Instancia.Credencial.Usuario.Length == 0))
                    {
                        OnOperacionError(mex);
                    }
                    else //ya existia un usuario valido, con lo que la sesion ha caducado
                    {
                        OnSesionCaducada();
                    }
                }
                catch (FaultException<ErrorServicio> ex)
                {
                    ((IClientChannel)client).Abort();
                    if (ex.Detail.TipoExcepcion.Equals(typeof(ValidationException).FullName))
                    {
                        ValidationException error = new ValidationException(ex.Detail.Mensaje) {CodigoError = ex.Detail.Id};
                        throw error;
                    }
                    if (ex.Detail.TipoExcepcion.Equals(typeof(SecurityException).FullName))
                    {
                        SecurityException error = new SecurityException {CodigoError = ex.Detail.Id};
                        throw error;
                    }
                    if (ex.Detail.TipoExcepcion.Equals(typeof(ServiceException).FullName))
                    {
                        ServiceException error = new ServiceException(ex.Detail.Mensaje);
                        // Comprobamos si hay aviso de triger en base de datos para mostrar su mensaje
                        if (ex.Detail != null && ex.Detail.Data != null && ex.Detail.Data.Contains("Triger"))
                            DevExpress.XtraEditors.XtraMessageBox.Show(ex.Detail.Data["Triger"].ToString());
                        OnOperacionError(error);
                    }
                    if (ex.Detail.TipoExcepcion.Equals(typeof(MessageSecurityException).FullName))
                    {
                        OnSesionCaducada();
                    }

                }
                catch (CommunicationException e)
                {
                    ((IClientChannel)client).Abort();
                    OnOperacionError(e);
                }
                catch (Exception e)
                {
                    ((IClientChannel)client).Abort();
                    OnOperacionError(e);
                }

            }

            public void CloseChannel()
            {
                ICommunicationObject canal = _channel as ICommunicationObject;
                if (canal != null)
                    canal.Close();
            }

            private void OnOperacionError(Exception ex)
            {
                Configurador.Instancia.OnOperacionError(ex);
            }

            private void OnSesionCaducada()
            {
                Configurador.Instancia.OnSesionCaducada();
            }
        }

    The exception ocurrs at CreateChannel method, executing _channel = base.CreateChannel();. Finally, this is the service interface:

            [ServiceContract]
        //[ServiceKnownType("GetKnownTypes", typeof(KnownTypesProvider))]
        public interface IContratoService
        {
            [OperationContract]
            ColeccionNegocioBase<ContratoEntidad> ObtenerContratos(ContratoFiltro filtroContrato, OrdenFiltro filtroOrden, bool completo);

            [OperationContract]
            ContratoEntidad EmitirContrato(ContratoEntidad contrato, bool esContratoTv);

            [OperationContract]
            ContratoEntidad ReEmitirContrato(ContratoEntidad contrato);

            [OperationContract]
            ContratoEntidad ModificarContrato(ContratoEntidad contrato, List<string> liCampos);

            [OperationContract]
            ColeccionNegocioBase<ContratoEntidad> CancelacionContratos(ColeccionNegocioBase<OrdenEntidad> coleccion);

            [OperationContract]
            ColeccionNegocioBase<ContratoEntidad> CancelacionCondicionalContratos(ColeccionNegocioBase<OrdenEntidad> coleccion);

            [OperationContract]
            ColeccionNegocioBase<ContratoEntidad> CancelacionContratosTv(ColeccionNegocioBase<OrdenTVPresentacionEntidad> coleccion);

            [OperationContract]
            ColeccionNegocioBase<ContratoEntidad> CancelacionCondicionalContratosTv(ColeccionNegocioBase<OrdenTVPresentacionEntidad> coleccion);

            [OperationContract]
            ColeccionNegocioBase<ContratoEntidad> EmisionContratos(ColeccionNegocioBase<OrdenEntidad> coleccion);

            [OperationContract]
            ColeccionNegocioBase<ContratoEntidad> EmisionContratosTv(ColeccionNegocioBase<OrdenTVPresentacionEntidad> coleccion, PlanificacionTVEntidad mPlanificacion);

            [OperationContract]
            ColeccionNegocioBase<ContratoEntidad> EmisionContratosTvSinPlanificacion(ColeccionNegocioBase<OrdenTVPresentacionEntidad> coleccion);

            [OperationContract]
            ColeccionNegocioBase<ContratoEntidad> ReemisionContratos(ColeccionNegocioBase<OrdenEntidad> coleccion);

            [OperationContract]
            int NumeroOrdenesContrato(int codigoContrato);

            [OperationContract]
            ColeccionNegocioBase<ContratoEntidad> ObtenerContratosDisponibles(ContratoFiltro filtroContrato);

            [OperationContract]
            void ActualizarObservacionesContrato(ColeccionNegocioBase<ContratoEntidad> coleccion, string pObservaciones);}
    viernes, 26 de agosto de 2016 9:50

Respuestas

  • Hola,

    revisa los namespaces  y el name de tus DataContracts no estén duplicados

    Ejemplo

    [DataContract(Namespace = "http://MiServicio/MiOperacion/1.0", Name = "Nombre")]



    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 8 de septiembre de 2016 8:11
    Moderador