我今天转换了我的WCF服务,使用WSHttpBinding而不是BasicHttpBinding。它仍处于开发阶段,因此我使用自签名证书。我遵循的示例位于Here
最终让代码工作就像示例所示(按照可以下载的代码中的配置示例),我决定像以前一样继续使用Channel Factories。
现在,当我调用WCF方法时,我可以清楚地看到我发送的对象填充了预期的值,但是如果我进入WCF端,则值是它们的默认值。例如,Guid将是Empty Guid,而int将是0. Always。
知道可能导致这种情况的原因是什么?这是我的一些代码:
在web.config中:
<add key="ClientCertificate" value="WcfClient" />
<add key="ServerCertificate" value="WcfServer" />
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="CustomBehavior">
<clientCredentials>
<clientCertificate findValue="WcfClient"
x509FindType="FindBySubjectName"
storeLocation="CurrentUser"
storeName="My" />
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IDocumentsService" closeTimeout="00:10:00"
openTimeout="00:10:00" sendTimeout="00:10:00" maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647" messageEncoding="Mtom" allowCookies="true">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Certificate" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:58790/DocumentsService.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IDocumentsService"
contract="DocumentsService.IDocumentsService"
name="WSHttpBinding_IDocumentsService"
behaviorConfiguration="CustomBehavior">
<identity>
<dns value="WcfServer" />
</identity>
</endpoint>
</client>
</system.serviceModel>
这是我的渠道工厂
public static class ServiceObjects
{
public static IDocumentsService DocumentsSVC { get { return GetDocServiceClient(); } }
#region Private Members
private static WSHttpBinding _DMBinding = new WSHttpBinding("WSHttpBinding_IDocumentsService");
private static EndpointIdentity _DMIdentity = EndpointIdentity.CreateDnsIdentity(ConfigurationManager.AppSettings.Get("ServerCertificate"));
private static EndpointAddress _DMEndpoint = new EndpointAddress(new Uri(ConfigurationManager.AppSettings.Get("DocumentsService")), _DMIdentity);
private static IDocumentsService GetDocServiceClient()
{
ChannelFactory<IDocumentsService> _docSvcFactory = new ChannelFactory<IDocumentsService>(_DMBinding, _DMEndpoint);
_docSvcFactory.Credentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust;
_docSvcFactory.Credentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, ConfigurationManager.AppSettings.Get("ClientCertificate"));
_docSvcFactory.Credentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.CurrentUser, StoreName.My, X509FindType.FindBySubjectName, ConfigurationManager.AppSettings.Get("ServerCertificate"));
return _docSvcFactory.CreateChannel();
}
#endregion
}
当我呼叫服务时,在客户端,例如:
private static Guid _UserID = (HttpContext.Current.User as Titan.Web.Classes.Identity.CustomPrincipal).UserId;
ServiceObjects.DocumentsSVC.GetDocumentsByFolderID(new DocumentRequest { CurrentUserID = _UserID })
我可以看到_UserID已填充,但在服务器端则不然。
这是我服务的配置
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding" closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="true" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Mtom">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Titan.WCF.Documents.DocumentsService" behaviorConfiguration="DocumentsServiceBehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="Titan.WCF.Documents.IDocumentsService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DocumentsServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<serviceCredentials>
<clientCertificate>
<!-- Remove the NoCheck in production, this is only for when we use a self signed cert -->
<authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck" />
</clientCertificate>
<serviceCertificate findValue="WCfServer"
storeLocation="CurrentUser"
storeName="My"
x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
答案 0 :(得分:1)
当然,由于您已在服务中更改了配置,因此需要更新服务引用,以便客户端也可以更新其配置。除非您这样做,否则客户端将继续使用旧配置调用该服务,当服务使用新配置设置运行时,该配置将从配置文件中读取。
这可能很累,但它就是这样。
答案 1 :(得分:0)
问题似乎在于您使用以下代码调用服务的方式:
ServiceObjects.DocumentsSVC.GetDocumentsByFolderID(new DocumentRequest { CurrentUserID = _UserID });
在这里,您尝试在不创建服务的代理对象的情况下调用服务功能。那是因为你在服务中写了一个静态类。
在WCF服务中,您不能使用静态类。您需要创建类的实例(服务代理对象),然后调用服务函数。
答案 2 :(得分:0)
我不确定为什么这会有所作为,但确实如此。
我需要更新我的服务引用。
我猜是一个新手的错误,但如果我做的唯一事情就是更改绑定,端点等,为什么会有所作为呢?