【问题标题】:WCF 4 - An existing connection was forcibly closed by the remote host when DataTable is returned from serviceWCF 4 - 从服务返回 DataTable 时,远程主机强制关闭现有连接
【发布时间】:2013-06-06 06:50:50
【问题描述】:

我的服务有一个返回 DataTable 的 OperationContract。每当我从这里获得访问权限时, 服务器错误提示“现有连接被远程主机强行关闭”

在服务端的IServie1.svc中,

[ServiceContract]
public interface IService1
{
    [OperationContract]
    bool HandShake(int branchId);

    [OperationContract]
    Investigation Synchronize(string tblName);

    [OperationContract]
    DataTable Synchronize1(string tblName);

在我的客户端代码中,

        Service1Client client = new Service1Client();

        GridView1.DataSource = client.Synchronize1("inv");

        GridView1.DataBind();

在服务的 Web.config 中,

 <system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="basic1" maxReceivedMessageSize="2147483647">
      <readerQuotas maxStringContentLength="2147483647"/>
    </binding>
  </basicHttpBinding>

</bindings>
<services>
  <service name="WcfService2.Service1" behaviorConfiguration="Service1Behavior">
    <endpoint
       address=""
        binding="basicHttpBinding"
        contract="WcfService2.IService1"
        bindingConfiguration="basic1"></endpoint>
    <endpoint
       address="Add2"
        binding="wsHttpBinding"
        contract="WcfService2.IService1"></endpoint>
    <endpoint
       address="mex"
       binding="mexHttpBinding"
        contract="IMetadataExchange"></endpoint>
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost/WcfService2/Service1.svc"/>
      </baseAddresses>
    </host>
  </service>

</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="Service1Behavior">
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
      <serviceMetadata httpGetEnabled="true" policyVersion="Policy15"/>
      <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
      <serviceDebug includeExceptionDetailInFaults="True"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />

在客户端的Web.config中,

<system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_IService1" maxReceivedMessageSize="2147483647">
      <readerQuotas maxStringContentLength="2147483647" />
    </binding>
  </basicHttpBinding>
  <wsHttpBinding>
    <binding name="WSHttpBinding_IService1" maxReceivedMessageSize="2147483647" />
  </wsHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost/WcfService2/Service1.svc"
    binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1"
    contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" />
  <!--<endpoint address="http://localhost/WcfService2/Service1.svc/Add2"
    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1"
    contract="ServiceReference1.IService1" name="WSHttpBinding_IService1">
    <identity>
      <servicePrincipalName value="host/Jenny-PC" />
    </identity>
  </endpoint>-->
</client>

【问题讨论】:

  • 正如 TuanHuynh 在下面指出的那样,在 WCF 中使用 DataTables(或任何其他非原始 .NET 类型)通常被认为是不好的做法。在您看到的错误的情况下,我相信 WCF 不能很好地序列化 DataTables,这会导致导致主机关闭连接的错误。您可以改用 DataSet,但我强烈建议您不要使用它。相反,返回一个包含数据的自定义对象。

标签: wcf


【解决方案1】:

返回 DataTable 并不总是做 Web 服务的最佳实践,想象你的消费者没有使用 .NET,他们将如何序列化消息,DataTable 在他们的语言中的对应物是什么,等等。

关于您的问题,我认为您应该添加诊断程序以便能够看到确切发生的情况: 将以下部分添加到 serviceModel

<diagnostics>
    <messageLogging
       logEntireMessage="true"
       logMalformedMessages="false"
       logMessagesAtServiceLevel="true"
       logMessagesAtTransportLevel="true"
       maxMessagesToLog="300000"
       maxSizeOfMessageToLog="2000000"/>
  </diagnostics>

此部分为第一级 app.config 或 web.config

<system.diagnostics>
<trace autoflush="true" />
<sources>
  <source name="System.ServiceModel"
          switchValue="Information, ActivityTracing"
          propagateActivity="true">
    <listeners>
      <add name="sdt"
          type="System.Diagnostics.XmlWriterTraceListener"
          initializeData="c:\SdrConfigExample.e2e"  />
    </listeners>
  </source>
  <source name="System.ServiceModel.MessageLogging">
    <listeners>
      <add name="messages"
      type="System.Diagnostics.XmlWriterTraceListener"
      initializeData="c:\messages.svclog" />
    </listeners>
  </source>
</sources>

当您发现时告诉我们;)

【讨论】:

  • 是的,DataSet 不是 Web 服务中的最佳实践。但是所有将使用我的 Web 服务的客户端肯定会使用 Window Forms 应用程序。但现在我正在考虑使用数据收集类而不是 DataSet 或 DataTable。
猜你喜欢
  • 2011-11-04
  • 1970-01-01
  • 2011-01-06
  • 2013-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多