使用 webHttpBinding 和安全模式传输添加对 WCF 服务的服务引用会导致配置文件不正确
我已经搜索了又搜索,但找不到解决方案。似乎遇到这种情况是比较常见的...通过 https 的 WCF REST 服务。当我添加服务引用时,所有代理类都是正确的,我可以创建服务中定义的对象、调用服务等。但是,我无法使用代理的客户端类创建已配置的客户端。我必须明确创建绑定、行为和端点并将它们添加到客户端。例如,根据我所有的研究,我应该能够做的是:
ServiceClient = new ServiceClient();
然后开始运行。但是,我要做的是:
WebHttpBinding serviceBinding = new WebHttpBinding(WebHttpSecurityMode.Transport);
serviceBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
EndpointAddress endPointAddress
= new EndpointAddress(<endpointaddress>);
// Create Service Client
ServiceClient = new ServiceClient(serviceBinding, endPointAddress);
// Add Web Behavior to the EndPoint
WebHttpBehavior webHttpBehavior = new WebHttpBehavior();
ServiceClient.Endpoint.Behaviors.Add(webHttpBehavior);
// Set up the request to POST with a wrapped request
WebInvokeAttribute postAttribute = new WebInvokeAttribute();
postAttribute.Method = "POST";
postAttribute.BodyStyle = WebMessageBodyStyle.WrappedRequest;
ServiceClient.Endpoint.Contract.Operations.Find(<operationname>).Behaviors.Add(postAttribute);
为了模仿服务配置:
<behaviors>
<endpointBehaviors>
<behavior name="AspNetAjaxBehaviorXml">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="AuthenticationServicesBehavior">
<serviceMetadata httpsGetEnabled="true" policyVersion="Policy15" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="LoggingServicesBehavior">
<serviceMetadata httpsGetEnabled="true" policyVersion="Policy15" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="True" />
<bindings>
<webHttpBinding>
<binding name="WebSslBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="AuthenticationServicesBehavior"
name="AuthenticationServices">
<endpoint address="authenticate" behaviorConfiguration="AspNetAjaxBehaviorXml"
binding="webHttpBinding" bindingConfiguration="WebSslBinding"
name="AuthenticationEndPoint" bindingNamespace="<mynamespace>"
contract="IService" />
</service>
“添加服务引用”给了我这样的信息:
<bindings>
<customBinding>
<binding name="AuthenticationEndPoint">
<!-- WsdlImporter encountered unrecognized policy assertions in ServiceDescription 'EchoAppsServices': -->
<!-- <wsdl:binding name='AuthenticationEndPoint'> -->
<!-- <sp:HttpsToken xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">..</sp:HttpsToken> -->
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap12" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
</binding>
</customBinding>
</bindings>
<client>
<endpoint binding="customBinding" bindingConfiguration="AuthenticationEndPoint"
contract="AuthenticationService"
name="AuthenticationEndPoint" />
</client>
我相信我无法创建开箱即用的默认客户端与 WsdlImporter 的问题有关。当我使用 svcutil 时,我遇到类似的错误:
Warning: The following Policy Assertions were not Imported:
XPath://wsdl:definitions[@targetNamespace='<mynamespace>']/wsdl:binding[@na
me='AuthenticationEndPoint']
Assertions:
<sp:HttpsToken xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolic
y'>..</sp:HttpsToken>
我确定它与我的自签名证书有关,但我无法让 makecert 为我提供一个带有 CA 的功能证书,不会导致我的 IIS 崩溃。
环境详情: VS2008 XP 64 位 .NET 3.5 IIS6
预先感谢您的帮助...
I have searched and searched and I cannot find a solution. It seems like it would be relatively common to run into this... WCF REST service over https. When I add the service reference all of the proxy classes are correct and I can create the objects defined in the service, call the services, etc. However, I can't create a configured client with the proxy's client classes. I have to explicity create the bindings, behaviors, and endpoints and add them to the client. FOr example, what I should be able to do, based on all of my research is:
ServiceClient = new ServiceClient();
And be off and running. However, what I have to do is:
WebHttpBinding serviceBinding = new WebHttpBinding(WebHttpSecurityMode.Transport);
serviceBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
EndpointAddress endPointAddress
= new EndpointAddress(<endpointaddress>);
// Create Service Client
ServiceClient = new ServiceClient(serviceBinding, endPointAddress);
// Add Web Behavior to the EndPoint
WebHttpBehavior webHttpBehavior = new WebHttpBehavior();
ServiceClient.Endpoint.Behaviors.Add(webHttpBehavior);
// Set up the request to POST with a wrapped request
WebInvokeAttribute postAttribute = new WebInvokeAttribute();
postAttribute.Method = "POST";
postAttribute.BodyStyle = WebMessageBodyStyle.WrappedRequest;
ServiceClient.Endpoint.Contract.Operations.Find(<operationname>).Behaviors.Add(postAttribute);
In order to mimic the service configuration:
<behaviors>
<endpointBehaviors>
<behavior name="AspNetAjaxBehaviorXml">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="AuthenticationServicesBehavior">
<serviceMetadata httpsGetEnabled="true" policyVersion="Policy15" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="LoggingServicesBehavior">
<serviceMetadata httpsGetEnabled="true" policyVersion="Policy15" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="True" />
<bindings>
<webHttpBinding>
<binding name="WebSslBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="AuthenticationServicesBehavior"
name="AuthenticationServices">
<endpoint address="authenticate" behaviorConfiguration="AspNetAjaxBehaviorXml"
binding="webHttpBinding" bindingConfiguration="WebSslBinding"
name="AuthenticationEndPoint" bindingNamespace="<mynamespace>"
contract="IService" />
</service>
The "Add Service Reference" is giving me this:
<bindings>
<customBinding>
<binding name="AuthenticationEndPoint">
<!-- WsdlImporter encountered unrecognized policy assertions in ServiceDescription 'EchoAppsServices': -->
<!-- <wsdl:binding name='AuthenticationEndPoint'> -->
<!-- <sp:HttpsToken xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">..</sp:HttpsToken> -->
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap12" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
</binding>
</customBinding>
</bindings>
<client>
<endpoint binding="customBinding" bindingConfiguration="AuthenticationEndPoint"
contract="AuthenticationService"
name="AuthenticationEndPoint" />
</client>
I believe my inability to create a default client that works out of the box is related to the problem with WsdlImporter. I get a similar error when I use svcutil:
Warning: The following Policy Assertions were not Imported:
XPath://wsdl:definitions[@targetNamespace='<mynamespace>']/wsdl:binding[@na
me='AuthenticationEndPoint']
Assertions:
<sp:HttpsToken xmlns:sp='http://schemas.xmlsoap.org/ws/2005/07/securitypolic
y'>..</sp:HttpsToken>
I'm sure it has something to do with my self signed cert, but I can't get makecert to give me a functioning cert with a CA that doesn't cause my IIS to crash.
Environment details:
VS2008
XP 64bit
.NET 3.5
IIS6
Thanks in advance for any help...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果你想创建客户端代理类,为什么要使用 webHttpBinding。为什么不直接使用 wsHttpBinding 呢?
webHttpBinding 的全部意义在于,您可以在客户端上使用标准 Http 工具包(例如 HttpWebRequest 和 Microsoft.Http.HttpClient)来访问服务。
If you want to create client proxy classes, why would you use webHttpBinding. Why not just use wsHttpBinding?
The whole point of webHttpBinding was so that you could use standard Http toolkits like HttpWebRequest and Microsoft.Http.HttpClient on the client to access the service.
不确定这是否只是一个拼写错误 - 但您的代码和配置不匹配。
请参阅您的代码:
但在您的配置中:
在代码中,您将
HttpClientCredentialType
设置为Windows
(集成 Windows 身份验证),但在配置中,您将其设置为无
。尝试更改您的配置以也使用 Windows:
然后重试。
如果您没有得到任何更好的结果:为什么不在导入后手动更新客户端配置呢?众所周知,WSDL 导入器有时会出现问题,而大多数情况下,只需动动脑筋并手动调整配置即可解决问题。您基本上只需将
和
部分复制到客户端配置中并定义
> 引用适当端点的部分 - 这几乎就是全部。Not sure if that's just a typo - but your code and config don't match.
See in your code:
but in your config:
In code, you set your
HttpClientCredentialType
toWindows
(integrated Windows authentication), but in config, you set it toNone
.Try changing your config to use Windows as well:
and try again.
If you don't get any better results : why not just update the client config manually, after the import? The WSDL importer is known to have hiccups here and there, and most often, just using your brain and manual config adaption can solve the problem. You basically just need to copy the
<endpointBehaviors>
and the<bindings>
sections into your client side config and define a<client>
section which references the appropriate endpoint - that's pretty much all.你提出了一个很好的观点,但我开始沿着这条路制作一个可以从客户端或服务器调用的 RESTful Web 服务。我现在可以按原样从两者调用它,但我必须显式配置服务器端。这是不可接受的,因为该应用程序将部署到多个最终用户,并且更改配置文件比修补更容易。我知道我可以创建多个端点,但我宁愿只为每个服务维护一个端点。
感谢你的回复。
You bring up a good point, but I started down this road to make a RESTful web service that can be called either from the client or the server. I can call it from both right now just the way it is but I have to explicitly configure the server side. This is unacceptable because this application will be deployed to multiple end users and it's easier to change a configuration file than it is to patch. I know that I could create multiple endpoints, but I would much rather only have to maintain one per service.
Thank you for your reply.