对象值默认

时间:2014-02-27 12:44:21

标签: c# wcf wshttpbinding

我今天转换了我的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>

3 个答案:

答案 0 :(得分:1)

当然,由于您已在服务中更改了配置,因此需要更新服务引用,以便客户端也可以更新其配置。除非您这样做,否则客户端将继续使用旧配置调用该服务,当服务使用新配置设置运行时,该配置将从配置文件中读取。

这可能很累,但它就是这样。

答案 1 :(得分:0)

问题似乎在于您使用以下代码调用服务的方式:

ServiceObjects.DocumentsSVC.GetDocumentsByFolderID(new DocumentRequest { CurrentUserID = _UserID });

在这里,您尝试在不创建服务的代理对象的情况下调用服务功能。那是因为你在服务中写了一个静态类。

在WCF服务中,您不能使用静态类。您需要创建类的实例(服务代理对象),然后调用服务函数。

答案 2 :(得分:0)

我不确定为什么这会有所作为,但确实如此。

我需要更新我的服务引用。

我猜是一个新手的错误,但如果我做的唯一事情就是更改绑定,端点等,为什么会有所作为呢?