【问题标题】:WCF ERROR: The server did not provide a meaningful reply;WCF 错误:服务器没有提供有意义的回复;
【发布时间】:2013-04-23 15:51:00
【问题描述】:

请有人帮我找出发生了什么。我的 WCF 服务运行良好,但现在突然出现此错误:

服务器没有提供有意义的回复;这可能是由于合同不匹配、会话过早关闭或内部 服务器错误

我必须说,当我选择数千条记录时它仍然有效,但是当数据很大时,我收到了这个错误,虽然之前它工作正常!

    private static string ConnString = "Server=127.0.0.1; Port=5432; Database=DBname; User Id=UName; Password=MyPassword;"
    DataTable myDT = new DataTable();

                NpgsqlConnection myAccessConn = new NpgsqlConnection(ConnString);
                myAccessConn.Open();
        string query = "SELECT * FROM Twitter";

                NpgsqlDataAdapter myDataAdapter = new NpgsqlDataAdapter(query, myAccessConn);

                myDataAdapter.Fill(myDT);
                foreach (DataRow dr in myDT.Rows)
                {
   **WHEN I HAVE TOO MANY RECORDS IT STOPS HERE**
        ...

web.config

<configuration>
    <system.web>
        <compilation debug="false" targetFramework="4.0" />
      <httpRuntime maxRequestLength="2147483647" executionTimeout="100000" />
    </system.web>
  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="System.ServiceModel"
              switchValue="Information, ActivityTracing"
              propagateActivity="true">
        <listeners>
          <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="Traces4.svclog"/>
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
  <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IDBService" closeTimeout="00:30:00"
                    openTimeout="00:30:00" receiveTimeout="00:30:00" sendTimeout="00:30:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Streamed"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
                        maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
    <client>
      <endpoint address="" binding="basicHttpBinding" 
          bindingConfiguration="BasicHttpBinding_IDBService" contract="DBServiceReference.IDBService"
          name="BasicHttpBinding_IDBService" />
    </client>
        <behaviors>
            <serviceBehaviors>
                <behavior name="">
                  <serviceMetadata httpGetEnabled="true" />
                  <serviceDebug includeExceptionDetailInFaults="true" />
                  <dataContractSerializer maxItemsInObjectGraph="2147483646" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
    </system.serviceModel>
</configuration>

客户端配置(已编辑)

<configuration>
        <system.serviceModel>
            <bindings>
                <basicHttpBinding>
                    <binding name="BasicHttpBinding_IRouteService" maxBufferSize="2147483647"
                        maxReceivedMessageSize="2147483647">
                        <security mode="None" />
                    </binding>
                    <binding name="BasicHttpBinding_IDBService" closeTimeout="00:30:00"
                        openTimeout="00:30:00" receiveTimeout="00:30:00" sendTimeout="00:30:00"
                        maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
                        transferMode="Buffered" >

                        <security mode="None" />
                    </binding>
                </basicHttpBinding>
                <customBinding>
                    <binding name="CustomBinding_IRouteService">
                        <binaryMessageEncoding />
                        <httpTransport maxReceivedMessageSize="2147483647"
                            maxBufferSize="2147483647" />
                    </binding>
                </customBinding>
            </bindings>

            <client>
                <endpoint address="http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc"
                    binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IRouteService"
                    contract="BingRoutingService.IRouteService" name="BasicHttpBinding_IRouteService" />
                <endpoint address="http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc/binaryHttp"
                    binding="customBinding" bindingConfiguration="CustomBinding_IRouteService"
                    contract="BingRoutingService.IRouteService" name="CustomBinding_IRouteService" />
                <endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDBService"
                    contract="DBServiceReference.IDBService" name="BasicHttpBinding_IDBService" />
            </client>
        </system.serviceModel>
    </configuration>

在我的文件 scvlog 中我没有得到任何异常! 我不知道我还能做些什么来了解问题出在哪里。 请有人帮助我!!!

【问题讨论】:

  • 这是完整的 web.config...?!我看不到system.serviceModel/services/service-section。
  • 是的,我需要查看更多配置。但是,由于有很多记录,您可能会遇到超时问题
  • 对不起,我已经编辑了客户端配置。 @Jeff,奇怪的是它之前工作过,超时或其他任何问题我都没有。
  • 您编辑了客户端配置。我的意思是web.config。它至少缺少服务的声明......
  • @justMe,是的,这就是我在 web.config 中的全部内容。我在代码中定义端点配置名称和地址: System.ServiceModel.EndpointAddress DBServiceEndpointAddress = new System.ServiceModel.EndpointAddress(new Uri(Application.Current.Host.Source, "../DBService.svc")); DBServiceReference.DBServiceClient DBClient = new DBServiceReference.DBServiceClient("BasicHttpBinding_IDBService", DBServiceEndpointAddress);

标签: wcf


【解决方案1】:

一个不同的答案,以防万一有人像我一样来到这里寻找问题的一般答案。

看起来做驴工作的 DataContractSerializer 非常挑剔,但并不总是将真正的错误传递给客户端。服务器进程在失败后立即死亡 - 因此找不到错误。在我的情况下,问题是一个用作标志的枚举,但没有用 [Flags] 属性装饰(挑剔或什么!)。

为了解决这个问题,我创建了一个序列化程序实例并在调试器中检查了错误;这是一个代码 sn-p,因为我手头有它。

编辑:响应 cmets 中的请求 ...

修改了代码 sn-p 以显示我现在使用的辅助方法。与以前大体相同,但在一个方便的通用包装器中。

public static T CheckCanSerialize<T>(this T returnValue) {
    var lDCS = new System.Runtime.Serialization.DataContractSerializer(typeof(T));

    Byte[] lBytes;
    using (var lMem1 = new IO.MemoryStream()) {
        lDCS.WriteObject(lMem1, returnValue);
        lBytes = lMem1.ToArray();
    }

    T lResult;
    using (var lMem2 = new IO.MemoryStream(lBytes)) {
        lResult = (T)lDCS.ReadObject(lMem2);
    }

    return lResult;
}

并且要使用this,而不是返回一个对象,而是在调用helper方法后返回对象,所以

public MyDodgyObject MyService() {
    ... do lots of work ...
    return myResult;
}

变成

public MyDodgyObject MyService() {
    ... do lots of work ...
    return CheckCanSerialize(myResult);
}

然后在服务停止关注之前抛出序列化中的任何错误,因此可以在调试器中进行分析。

注意;我不建议将调用留在生产代码中,它具有序列化和反序列化对象的开销,一旦调试代码就没有任何真正的好处。

希望这对某人有所帮助 - 我已经浪费了大约 3 个小时试图找到它。

【讨论】:

  • 我真的很想试试你的建议以获得真正的错误信息,但不清楚应该在哪里实施。
  • 这应该是服务在将结果发送回客户端之前所做的最后一件事。大多数错误都可以在服务中捕获并以直接的方式处理,但是在方法调用的结果离开服务时转换转换的问题并不容易发现;这种技术模仿了最终的序列化,因此可以在服务消失之前看到错误。
  • 你太棒了!!这解决了我的问题,不幸的是我被困了几天......如果我能拥抱你,我会的,但非常感谢你!
  • 就像@friggle 和其他人一样,我无法完全理解如何应用您的解决方案。您能否举一个更完整的示例,可能带有突出显示调用客户端代码和服务器 WCF 代码的代码(我认为这对于复制解决方案非常有用)。
  • @UlyssesAlves 我已经修改了代码。调用客户端代码中没有什么可做的,这仅在服务器中。将您的返回对象作为 CheckCanSerialize 的参数,它将序列化然后反序列化。如果进程有任何问题,您应该能够在服务调用被清理之前在调试器中看到它。
【解决方案2】:

我不知道这是否真的可以作为答案,但我尝试将 web.config&lt;security mode="None" /&gt; 更改为 &lt;security mode="Transport" /&gt; 并且成功了!!!

我要注意的是,这部分应该只在 web.config 中进行更改,并且在客户端配置中保持&lt;security mode="None" /&gt;,因为在这两个中使用 Transport 都不起作用! p>

所以在那之后,我决定尝试再次回到None security,它工作了几分钟,然后又停止了,它又出现了错误:

服务器没有提供有意义的回复;这可能是由合同不匹配、会话过早关闭或内部服务器错误引起的

所以看来我的解决方案是在web.config中设置

security mode to Transport

【讨论】:

  • 不幸的是,我又遇到了同样的错误,我不明白出了什么问题,为什么有时我的 WCF 服务可以工作,而有时我会收到这个错误。请,如果有人有任何想法,请写信给我!
  • 我曾尝试使用 fiddler,我注意到当出现错误且服务正常工作且未返回错误时,响应正文始终为“124.300.487 字节”。它有可能在客户端崩溃吗?还有一件事,在测试过程中,我也遇到过几次“System.InsufficientMemoryException 无法分配 233702096 字节的托管内存缓冲区。可用内存量可能很低。”
  • 你有没有明确解决这个问题的办法?
【解决方案3】:

就我而言,我正在处理一个与 WCF Web 服务通信的 Windows 应用程序项目。 使用 netTcpBinding 的 Web 服务正在返回一个 Stream 对象(图片)。

由于 windows 应用程序没有配置文件,因此使用默认值进行绑定。只需在客户端后端代码上扩展 MaxReceivedMessageSize 即可解决我的问题。

var API = new StreamService.StreamServiceClient(
  new System.ServiceModel.NetTcpBinding(System.ServiceModel.SecurityMode.None)
  {
    MaxReceivedMessageSize = 2147483647
  },
  new System.ServiceModel.EndpointAddress("net.tcp://machine/app/service.svc")
);

【讨论】:

    【解决方案4】:

    有时此问题是由由于绑定中的默认值而被剪切的过大消息引起的。

    您应该在 app.config 文件中的绑定中添加具有足够大值的 ma​​xReceivedMessageSize、maxBufferPoolSize 和 maxBufferSize - 这应该可以解决问题:)

    例子:

    <bindings>
    <netTcpBinding>
    <binding 
    name="ExampleBinding" closeTimeout="00:01:00"
    maxReceivedMessageSize="73400320"
    maxBufferPoolSize="70000000"
    maxBufferSize="70000000"/>
    </netTcpBinding>
    </bindings>
    

    祝你好运!

    【讨论】:

      【解决方案5】:

      在我的例子中,我正在开发一个 MVC 应用程序并且我已经改变了

      maxReceivedMessageSize ="10000000"
      

      maxReceivedMessageSize ="70000000"
      

      它成功了!这是因为来自网络服务器的响应超过了maxReceivedMessageSize ="10000000"
      所以我将maxReceivedMessageSize 增加到maxReceivedMessageSize ="70000000"

      【讨论】:

        【解决方案6】:

        根据我对这个错误的经验,只需检查服务主机的事件日志,看看实际的根异常是什么。

        【讨论】:

        • 这实际上是调试问题的最佳方式。就我而言,我在事件日志中记录了 WCF 的问题,如下所示:异常:System.ServiceModel.ServiceActivationException:由于编译期间出现异常,无法激活服务“/INT.ComplianceService/ComplianceService.svc”。异常消息是:内存门检查失败,因为可用内存(223719424 字节)小于总内存的 5%。因此,该服务将无法用于传入请求。
        【解决方案7】:

        对我来说,这是从数据库中检索到的项目的延迟加载列表。

        WCF 接收器会尝试迭代它们,这会尝试进入数据库,这显然无法工作。

        【讨论】:

        • 我可能拿了 Enumerable 并做了.ToArray().ToList()(在数据访问层),以持久化它并避免以后的延迟加载。
        【解决方案8】:

        在 BizTalk 中,我们使用来解决此问题。

        该问题的发生主要是由于来自服务的消息的大小。所以我们需要将接收消息的大小从 65,356 增加到 2,365,60。它对我有用。

        enter image description here

        【讨论】:

          【解决方案9】:

          ASP.NET 应用程序可以使用发出请求的用户的 Windows 身份(用户帐户)执行。模拟通常用于依赖 Microsoft Internet 信息服务 (IIS) 对用户进行身份验证的应用程序中。默认情况下禁用 ASP.NET 模拟。

          启用此选项,您的 API 将开始工作 - 它处于 IIS 身份验证中

          【讨论】:

            【解决方案10】:

            在我的例子中,从 .NET Framework 4.5 升级到 .NET Framework 4.8 后,我必须删除用 DataMemberAttribute 修饰的属性的只读修饰符

            【讨论】:

              猜你喜欢
              • 2011-02-08
              • 1970-01-01
              • 2012-11-19
              • 1970-01-01
              • 2011-08-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-10-08
              相关资源
              最近更新 更多