怎样做?通过 Https 的 WCF 自定义绑定
我正在尝试在面向外部的网络场上设置一个供内部使用的 WCF 服务(我们内部没有网络场,我需要此服务进行故障转移和负载平衡)。
要求:
- PerSession 状态,因为我们需要服务为每个会话保留可变数据。
- HTTPS。经过大量谷歌搜索后,我读到我需要创建一个 customBinding,我已经完成了,但不确定它是否正确。
- 更大的消息大小,因为参数之一是 byte[] 数组,最大可为 5mb。
- 无需手动编辑客户端 app.config。即,我需要开发人员仅添加服务引用,然后开始使用该对象,而无需繁琐地更改 app.config。
注意:我之前已经让此服务在 HTTP 下正确工作(使用 wsHttpBinding)。 我也让它在 HTTPS 下工作,但它不支持 PerSession 状态,并且每次函数调用都会丢失内部变量值。
我目前从测试工具中收到此错误:
在 ServiceModel 客户端配置部分中找不到引用协定“AppMonitor.IAppMonitorWcfService”的默认端点元素。这可能是因为没有找到适用于您的应用程序的配置文件,或者因为在客户端元素中找不到与此协定匹配的端点元素。
注意:错误是在 Test Harness EXE 上出现的,该 EXE 直接在服务引用下引用了 WCF 服务。这不是我读过的 exe 引用另一个对象,然后引用 WCF 服务的问题。
浏览到 URL 时,WSDL 正确显示。
Web.Config:
<system.serviceModel>
<services>
<service name="AppMonitor.AppMonitorWcfService" behaviorConfiguration="ServiceBehavior">
<endpoint address="" binding="customBinding" bindingConfiguration="EnablePerSessionUnderHttps" contract="AppMonitor.IAppMonitorWcfService"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<customBinding>
<binding name="EnablePerSessionUnderHttps" maxReceivedMessageSize="5242880">
<reliableSession ordered="true"/>
<textMessageEncoding>
<readerQuotas maxDepth="64" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpsTransport authenticationScheme="Anonymous" requireClientCertificate="false"/>
</binding>
</customBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
EXE 的 App.config(添加服务引用时自动生成):
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="CustomBinding_IAppMonitorWcfService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="true" />
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client />
</system.serviceModel>
</configuration>
我不确定为什么 app.config 显示 wsHttpBinding?这不应该是自定义绑定吗? 我真的不想编辑 app.config,因为该服务将由数十个开发人员使用,我希望他们能够添加服务引用,然后就可以走了。
使用VS2008、.NET 3.51。 我认为服务器是IIS7,Win Server 2008,如果需要可以确认。
I'm trying to setup a WCF service for internal use, on our external facing web-farm (we don't have a web farm internally, and I need this service to have failover and load-balancing).
Requirements:
- PerSession state, as we need the service to retain variable data for each session.
- HTTPS. After lots of googling i've read I needed to create a customBinding, which I've done, but not sure if it is correct.
- Larger message size, as one of the parameters is a byte[] array, which can be a max of 5mb.
- no requirement to manually edit the client-side app.config. ie, I need the Developer to just add the service reference, and then starts using the object without fiddly changing of app.config.
Note: I've previously had this service working under HTTP correctly (using wsHttpBinding).
I've also had it working under HTTPS, but it didn't support PerSession state, and lost internal variable values each function call.
I'm currently getting this error from the test harness:
Could not find default endpoint element that references contract 'AppMonitor.IAppMonitorWcfService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
NOTE: The error is arising on an Test Harness EXE, that has the WCF service referenced directly under Service References. This is not the problem of an exe referencing another object, that then references the WCF service, that i've read about.
The WSDL is showing correctly when browsing to the URL.
Web.Config:
<system.serviceModel>
<services>
<service name="AppMonitor.AppMonitorWcfService" behaviorConfiguration="ServiceBehavior">
<endpoint address="" binding="customBinding" bindingConfiguration="EnablePerSessionUnderHttps" contract="AppMonitor.IAppMonitorWcfService"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<customBinding>
<binding name="EnablePerSessionUnderHttps" maxReceivedMessageSize="5242880">
<reliableSession ordered="true"/>
<textMessageEncoding>
<readerQuotas maxDepth="64" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<httpsTransport authenticationScheme="Anonymous" requireClientCertificate="false"/>
</binding>
</customBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
EXE's App.config (auto-generated when adding the Service Reference):
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="CustomBinding_IAppMonitorWcfService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="true" />
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client />
</system.serviceModel>
</configuration>
I'm not sure why the app.config is showing wsHttpBinding? Shouldn't this be customBinding?
I really don't want to have to edit the app.config, as this service will be used by dozens of developers, and I want them to just be able to add the Service Reference, and away they go.
Using VS2008, .NET 3.51.
I think server is IIS7, Win Server 2008, can confirm if needed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,您的问题是您尚未为您的服务定义地址。记住端点的 ABC:地址绑定合同。
您需要为该服务定义一个地址,该地址很大程度上由 .svc 文件控制,并且可以从 IIS 浏览该文件。无论该 .svc 文件的 URL 是什么,您都可以附加您定义的地址(在您的情况下为空字符串),然后将其添加到顶部。因此,如果我将 myservice.svc 文件放在根目录中,它将变为
https://localhost/myservice.svc/
在您的情况下
ServiceAddress=""
所以 URL 是https://localhost/myservice.svc/
。有关详细信息,请参阅此处。
OK, your problem is that you have not defined an Address for your service. Remember ABC of the endpoint: Address-Binding-Contract.
You need to define an address for the service which is pretty much governed by your .svc file and where the file can be browsed from your IIS. Whatever URL of that .svc file, you append the address you have defined (in your case empty string) and then it is added on top. So if I am putting myservice.svc file in the root, it becomes
https://localhost/myservice.svc/<ServiceAddress>
In your case
ServiceAddress=""
so URL ishttps://localhost/myservice.svc/
.See here for more info.