zoukankan      html  css  js  c++  java
  • 如何在ADO.NET Data Service的解决方案中修改最大传输数据量

    1.问题描述:

    如果你在使用ADO.NET Data Service做应用开发,那么有时候你可能会遇到如下的情况,尤其是你传输的数据量比较大的情况下,例如要上传或者下载一个比较大的文件时。

    image

    System.Net.WebException was unhandled by user code
      Message=The underlying connection was closed: An unexpected error occurred on a receive.
      Source=System
      StackTrace:
           at System.Net.HttpWebRequest.GetResponse()
           at System.Data.Services.Client.DataServiceContext.SaveResult.BatchRequest(Boolean replaceOnUpdate)
           at System.Data.Services.Client.DataServiceContext.SaveChanges(SaveChangesOptions options)
           at System.Data.Services.Client.DataServiceContext.SaveChanges()
           at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
           at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
           at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
           at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
           at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
           at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
           at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
           at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
           at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
           at System.Windows.Forms.Control.WndProc(Message& m)
           at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
           at System.Windows.Forms.ToolStrip.WndProc(Message& m)
           at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
      InnerException: System.IO.IOException
           Message=Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
           Source=System
           StackTrace:
                at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
                at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)
                at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)
           InnerException: System.Net.Sockets.SocketException
                Message=An existing connection was forcibly closed by the remote host
                Source=System
                ErrorCode=10054
                NativeErrorCode=10054
                StackTrace:
                     at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
                     at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
                InnerException:

    如果你无法看到如上的错误消息,那么你需要在服务里面开启一个选项

            public static void InitializeService(DataServiceConfiguration config)
            {
                // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
                // Examples:
                config.SetEntitySetAccessRule("*", EntitySetRights.All);
                config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
                config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
                config.UseVerboseErrors = true;
    
                
            }
    

    2.原因分析:

    当然,其实即便你看到了如上的错误消息,估计你也是一头雾水。事实上,上面的错误消息中并没有告诉你问题的真相。(所以我才要写这篇文章的嘛,呵呵)

    出现这个问题到底是什么原因呢?

    • WCF服务对最大传输的数据量有限制。默认是64KB,即65536BYTE. 因为ADO.NET Data Service说到底是一个WCF服务,只不过它使用的binding是比较特殊的罢
    • ASP.NET执行引擎本身对请求数据的长度有限制,默认为4MB(4096KB)。 因为我们的ADO.NET Data Service是宿主在ASP.NET网站中,对它的请求当然首先要能够发送给ASP.NET引擎。(其实,数据发送到了服务器之后,会有两种处理的模式,默认情况下WCF是有一套独立的处理管道,但与此同时也可以设置为所谓的ASP.NET兼容模式。这个话题这里不多展开了)

    3.解决方案:

    了解了如上的原因,我们就可以设法来解决它

    首先,设置WCF的最大消息数据大小为10MB(这里只是举例,你可以根据需要设置为你希望的大小)

      <system.serviceModel>
        <bindings>
          <webHttpBinding>
            <binding  name="my" maxReceivedMessageSize="10485760"></binding>
            <!--最大传输数据量为10MB:10*1024*1024-->
          </webHttpBinding>
        </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="">
              <serviceMetadata httpGetEnabled="true" />
              <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
        <services>
          <service name="Web.AdministrationService">
            <endpoint address="" binding="wsHttpBinding" contract="Web.IAdministrationService"></endpoint>
          </service>
          <service name="Web.MyDataService">
            <endpoint address="" binding="webHttpBinding" bindingConfiguration="my" contract="System.Data.Services.IRequestHandler"></endpoint>
          </service>
          
        </services>
      </system.serviceModel>

    【注意】大家可以看到,ADO.NET Data Service所使用的binding是webHttpBinding,它的contract是System.Data.Service.IRequestHandler

    【注意】这里的maxReceivedMessageSize单位是Byte,所以是10*1024*1024

    接下来,我们还需要设置网站级别处理请求的最大长度

    <httpRuntime maxRequestLength="10240"/>
    【注意】这个参数的单位是KB,所以是10*1024即可(关于单位不统一这一点,我是颇有微词的,很多地方单位都不一样,让你不得不记住那么多东西,例如同样的问题还存在于设置timeout的地方,这里就不多说了)
     
    完成上面两个设置之后,再次运行程序,就不会遇到错误了。然后,整个世界清静了……感觉不错 
     
  • 相关阅读:
    HLG 1522 子序列的和【队列的应用】
    POJ 3273 Monthly Expense【二分】
    HDU 4004 The Frog's Games 【二分】
    POJ 2001 Shortest Prefixes【第一棵字典树】
    POJ 2823 Sliding Window【单调对列经典题目】
    HDU 1969 Pie 【二分】
    POJ 3125 Printer Queue【暴力模拟】
    POJ 3250 Bad Hair Day【单调栈】
    字典树【模板】
    验证码 Code
  • 原文地址:https://www.cnblogs.com/chenxizhang/p/1754648.html
Copyright © 2011-2022 走看看