在C#中以编程方式创建WCF客户端的标头(wsse)部分

如何以编程方式在app #config中创建app.config服务设置的以下部分:

     someusername somepassword      

我设法从c#生成绑定部分(上面没有包含)和端点部分。 我无法创建标题部分。

出现的错误是:(这是因为当我从c#生成所有内容时,我没有标题部分)

此服务需要 ,缺少该服务。

header部分很重要,好像我从配置中排除它并使用config运行代码它也会产生上述错误。

我不想使用web.config / app.config。 我必须从C#运行所有东西。 (上面的app.config工作正常,但我想通过c#做同样的事情)

注意:以下更新是基于以下提供的解决方案请通过以下解决方案的评论,以获得更好的理解

更新1 :(首先以编程方式使用BasicHttpBinding)

 BasicHttpBinding binding = new BasicHttpBinding(); binding.Name = "Contact"; binding.CloseTimeout = TimeSpan.FromMinutes(1); binding.OpenTimeout = TimeSpan.FromMinutes(1); binding.ReceiveTimeout = TimeSpan.FromMinutes(10); binding.SendTimeout = TimeSpan.FromMinutes(1); binding.AllowCookies = false; binding.BypassProxyOnLocal = false; binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard; binding.MaxBufferSize = 524288; binding.MaxBufferPoolSize = 524288; binding.MaxReceivedMessageSize = 524288; binding.MessageEncoding = WSMessageEncoding.Text; binding.TextEncoding = System.Text.Encoding.UTF8; binding.TransferMode = TransferMode.Buffered; binding.UseDefaultWebProxy = true; binding.ReaderQuotas.MaxDepth = 32; binding.ReaderQuotas.MaxStringContentLength = 65536; binding.ReaderQuotas.MaxArrayLength = 131072; binding.ReaderQuotas.MaxBytesPerRead = 32768; binding.ReaderQuotas.MaxNameTableCharCount = 131072; binding.Security.Mode = BasicHttpSecurityMode.Transport; binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None; binding.Security.Transport.Realm = ""; binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName; binding.Security.Message.AlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Default; CustomBinding customBinding = new CustomBinding(binding); SecurityBindingElement element = customBinding.Elements.Find(); // Remove security timestamp because it is not used by your original binding //element.IncludeTimestamp = false; (element is NULL in my case) EndpointAddress endpoint = new EndpointAddress("https://myserviceaddress"); PostingWebServiceClient client = new PostingWebServiceClient(customBinding, endpoint); client.ClientCredentials.UserName.UserName = "myusername"; client.ClientCredentials.UserName.Password = "mypassword"; client.getActiveChannels(new getActiveChannels()); 

直接使用自定义Bindgin:

 SecurityBindingElement securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement(); securityElement.IncludeTimestamp = false; TextMessageEncodingBindingElement encodingElement = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8); HttpsTransportBindingElement transportElement = new HttpsTransportBindingElement(); CustomBinding customBinding = new CustomBinding(securityElement, encodingElement, transportElement); EndpointAddress endpoint = new EndpointAddress("https://myserviceaddress"); PostingWebServiceClient client = new PostingWebServiceClient(customBinding, endpoint); client.ClientCredentials.UserName.UserName = "myusername"; client.ClientCredentials.UserName.Password = "mypassword"; client.getActiveChannels(new getActiveChannels()); 

在这种情况下,您不必直接配置标头,因为您的方案应该直接由BasicHttpBindingCustomBinding支持。

如果需要从C#配置它,则必须在代码中创建绑定:

 // Helper binding to have transport security with user name token BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential); binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName; // Rest of your binding configuration comes here // Custom binding to have access to more configuration details of basic binding CustomBinding customBinding = new CustomBinding(binding); SecurityBindingElement element = customBinding.Elements.Find(); // Remove security timestamp because it is not used by your original binding element.IncludeTimestamp = false; EndpointAddress address = new EndpointAddress("https://..."); ProxyWebServiceClient client = new ProxyWebServiceClient(customBinding, address); client.ClientCredentials.UserName.UserName = "..."; client.ClientCredentials.UserName.Password = "..."; 

其他解决方案是直接构建自定义绑定,而不是从基本绑定开始:

 SecurityBindingElemetn securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement(); securityElement.IncludeTimestamp = false; TextMessageEncodingBindingElement encodingElement = new TextMessageEncodingBindingElement(MessageVersion.Soap11, Encoding.UTF8); HttpsTransportBindingElement tranportElement = new HttpsTransportBindingElement(); // Other configurations of basic binding are divided into properties of // encoding and transport elements CustomBinding customBinding = new CustomBinding(securityElement, encodingElement, transportElement); EndpointAddress address = new EndpointAddress("https://..."); ProxyWebServiceClient client = new ProxyWebServiceClient(customBinding, address); client.ClientCredentials.UserName.UserName = "..."; client.ClientCredentials.UserName.Password = "..."; 

查看此StackOverflow问题的已接受答案。 它显示了如何以编程方式将客户端凭据添加到代理。 它还显示了在客户端端点配置XML中添加标头,这是我以前从未见过的。