代码之家  ›  专栏  ›  技术社区  ›  Paul Mrozowski

在wcf中设置clientcredentials时,获取“object is read only”错误

  •  17
  • Paul Mrozowski  · 技术社区  · 16 年前

    我有一个由名为ServerClient的Visual Studio(客户端)生成的代理对象。我正在尝试设置clientcredentials.username.username/password,然后使用此代码打开新连接:

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

    一旦代码到达用户名行,它就会失败,并出现“object is read-only”错误。我知道如果连接已经打开或出现故障,就会发生这种情况,但此时我还没有调用context.open()。

    我已经将绑定(使用nettcpbinding)配置为使用message作为其安全模式,messageclientcredentialtype设置为username。

    有什么想法吗?

    11 回复  |  直到 6 年前
        1
  •  12
  •   Gerhard    12 年前

    我注意到,在为服务创建了代理类的实例之后,我可以设置一次用户名和密码而不会出错,并成功调用我的WebService。当我再次尝试在现有实例上设置用户名和密码时(当然不需要),我会得到您提到的“对象是只读的”错误。为我设置每个实例生存期一次的值。

        2
  •  8
  •   Paul Mrozowski    16 年前

    似乎您只能在安装周期的早期访问这些属性。如果我重写代理类(serverclient)中的构造函数,我就可以设置这些属性:

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

    我开始感激那些建议不要使用Vs提供的自动生成的代理的人。

        3
  •  5
  •   Gareth maartenba    6 年前

    解决方案如下:

    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);
    
        4
  •  1
  •   Eugene Yokota    16 年前

    我有相似的密码 UserName 好的:

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

    尝试在app.config中创建绑定名为的代理。

        5
  •  1
  •   Blue Clouds    7 年前

    如果通过->添加服务引用->高级->添加Web引用->URL/WSDL(本地磁盘文件)添加服务引用,则不会发生这种情况。

        6
  •  1
  •   Atul    6 年前

    我正面临这个问题,我试图创建一个通用方法来为不同的端点创建客户机。

    我是如何做到这一点的。

        public static T CreateClient<T>(string url) where T : class
        {
            EndpointAddress endPoint = new EndpointAddress(url);
            CustomBinding binding = CreateCustomBinding();
    
            T client = (T)Activator.CreateInstance(typeof(T), new object[] { binding, endPoint });
            SetClientCredentials(client);
    
            return client;
        }
    
        public static void SetClientCredentials(dynamic obj)
        {
            obj.ChannelFactory.Endpoint.Behaviors.Remove<ClientCredentials>();
            obj.ChannelFactory.Endpoint.Behaviors.Add(new CustomCredentials());
    
            obj.ClientCredentials.UserName.UserName = "UserId";
            obj.ClientCredentials.UserName.Password = "Password";
        }
    
        7
  •  0
  •   Mike Two    16 年前

    我认为您的问题可能与InstanceContext的使用有关。我认为这只是服务器端的双工通信通道所需要的。

    我承认我对此不确定,但我认为在本例中,您是在告诉客户机使用现有的实例上下文,因此它认为已经有一个正在运行的服务,并且不允许更改。

    是什么推动了InstanceContext的使用?

        8
  •  0
  •   Kwal    15 年前

    如果使用双工客户端,则在实例化它时,将使用现有凭据初始化派生客户端的DuplexClientBase中的DuplexChannelFactory,以便它可以打开回调通道,这就是凭据将为只读的原因。

    我回答了Mike的问题,还问了一个问题,如果您不打算使用它固有的传输级安全性,为什么要使用nettcpbinding?也许基于HTTP的绑定更适合?这将允许您使用基于证书的安全性,我相信可以在实例化后对其进行修改。( http://msdn.microsoft.com/en-us/library/ms576164.aspx )

        9
  •  0
  •   Shane    15 年前

    在黑暗中拍摄,但是nettcpbinding允许用户名和密码验证吗?尝试使用HTTP绑定使用应用程序层(SOAP)安全性

        10
  •  0
  •   Fabienne Bonzon    11 年前

    正确的语法是:

    //删除clientCredentials行为。 client.channelFactory.endpoint.behaviors.remove<clientCredentials>();

    //将自定义客户端凭据实例添加到行为集合中。 client.channelFactory.endpoint.behaviors.add(new myclientcredentials());

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

    这对我很有用。

        11
  •  0
  •   savitha    10 年前

    我也面临同样的问题,当我更改代码时,我的代码开始工作,即在初始化客户机对象后立即为客户机凭证分配值。

    这是解决方案,

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