WCF文件上载大文件

时间:2013-02-03 00:25:35

标签: wcf

过去两天我一直在做一些研究,以找到解决问题的办法,但无济于事。

我已经创建了一个像这样的WCF服务:

[OperationContract]
void CopyMemberFile(string memberNumber, string fileName, byte[] fileBytes);

我从我的客户端这样从page_load事件中调用它:

byte[] filebytes = null;

using (Stream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
{
     filebytes = new byte[fs.Length];
     fs.Read(filebytes, (int)0, (int)fs.Length);
}

client.CopyMemberFile(memberNumber, Path.GetFileName(file), filebytes);

我的配置如下:

客户端配置:

<configuration>
  <system.web>
    <authorization>
      <allow users="*"/>
    </authorization>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
        <add assembly="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" />
        <add assembly="System.Speech, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </assemblies>
    </compilation>
    <authentication mode="Forms">
    <forms loginUrl="~/Account/Login.aspx" timeout="300" cookieless="UseUri" />
  </authentication>
  <membership>
    <providers>
      <clear />
        <add name="AspNetSqlMembershipProvider"
             type="System.Web.Security.SqlMembershipProvider" 
             connectionStringName="ApplicationServices" 
             enablePasswordRetrieval="false" 
             enablePasswordReset="true" 
             requiresQuestionAndAnswer="false" 
             requiresUniqueEmail="false"
             maxInvalidPasswordAttempts="5" 
             minRequiredPasswordLength="6" 
             minRequiredNonalphanumericCharacters="0" 
             passwordAttemptWindow="10" 
             applicationName="/" />
    </providers>
  </membership>
  <profile>
    <properties>
      <add name="FirstName"/>
      <add name="LastName"/>
      <add name="MemberNumber"/>
      <add name="LastVisit" type="System.DateTime"/>
    </properties>
    <providers>
      <clear />
        <add name="AspNetSqlProfileProvider" 
             type="System.Web.Profile.SqlProfileProvider"
             connectionStringName="ApplicationServices" 
             applicationName="/" />
    </providers>
  </profile>
  <roleManager enabled="false">
    <providers>
      <clear />
        <add name="AspNetSqlRoleProvider" 
             type="System.Web.Security.SqlRoleProvider" 
             connectionStringName="ApplicationServices" 
             applicationName="/" />
        <add name="AspNetWindowsTokenRoleProvider"
             type="System.Web.Security.WindowsTokenRoleProvider" 
             applicationName="/" />
    </providers>
  </roleManager>
  <httpHandlers>
    <remove verb="*" path="*.asmx"/>
    <add verb="*" path="*.asmx" validate="false" 
         type="System.Web.Script.Services.ScriptHandlerFactory" />
    <add path="Telerik.Web.UI.WebResource.axd" 
         type="Telerik.Web.UI.WebResource" verb="*" validate="false" />
  </httpHandlers>
  <httpRuntime maxRequestLength="1048576"/>
</system.web>
<system.serviceModel>
  <behaviors>
    <endpointBehaviors>
      <behavior name="online.members.asp.Services.MembersOnlineSeviceAjaxAspNetAjaxBehavior">
        <enableWebScript />
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
                             multipleSiteBindingsEnabled="true" />
  <services>
    <service name="online.members.asp.Services.MembersOnlineSeviceAjax">
      <endpoint address="" behaviorConfiguration="online.members.asp.Services.MembersOnlineSeviceAjaxAspNetAjaxBehavior"
                binding="webHttpBinding" 
                contract="online.members.asp.Services.MembersOnlineSeviceAjax" />
    </service>
  </services>
  <bindings>
    <basicHttpBinding>
      <binding name="BasicHttpBinding_IMembershipApplications" 
                     closeTimeout="00:01:00"
                     openTimeout="00:01:00" 
                     receiveTimeout="00:10:00" 
                     sendTimeout="00:01:00"
                     allowCookies="false" 
                     bypassProxyOnLocal="false" 
                     hostNameComparisonMode="StrongWildcard"
                     maxBufferSize="2147483647" 
                     maxBufferPoolSize="2147483647" 
                     maxReceivedMessageSize="2147483647"
                     messageEncoding="Text" 
                     textEncoding="utf-8" 
                     transferMode="Buffered"
                     useDefaultWebProxy="true">
        <readerQuotas maxDepth="128" 
                      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="http://localhost:58119/MembershipApplications.svc"
              binding="basicHttpBinding"
              bindingConfiguration="BasicHttpBinding_IMembershipApplications"
              contract="MembershipApplicationsServiceReference.IMembershipApplications"
              name="BasicHttpBinding_IMembershipApplications" />
  </client>
</system.serviceModel>

服务配置:

<configuration>
  <system.web>
    <roleManager enabled="true" />
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

我得到的错误是:

3/02/2013 11:12:39 AM: Upload.aspx Error: The remote server returned an unexpect
ed response: (400) Bad Request.
Server stack trace:
   at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResp
onse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory factor
y, WebException responseException, ChannelBinding channelBinding)
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpCha
nnelRequest.WaitForReply(TimeSpan timeout)
   at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeS
pan timeout)
   at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message messag
e, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean on
eway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan tim
eout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCall
Message methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage req
Msg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgDa
ta, Int32 type)
   at online.members.asp.MembershipApplicationsServiceReference.IMembershipAppli
cations.CopyMemberFile(String memberNumber, String fileName, Byte[] fileBytes)`

我可以上传文件,每个文件只有几KB,但任何大于8KB的文件都会失败

任何帮助都会很棒。

致电代码:

protected void Page_Load(object sender, EventArgs e)
{
    var file = Request.Form["name"];            
    var memberNumber = Request.Form["memberNumber"];
    var tempId = Guid.NewGuid();

    var client = new MembershipApplicationsServiceReference.MembershipApplicationsClient();

    client.LogEvent("Entered Upload.aspx");

    try
    {
        byte[] filebytes = null;

        using (Stream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
        {
            filebytes = new byte[fs.Length];
            fs.Read(filebytes, (int)0, (int)fs.Length);

            client.LogEvent("Starting service call from Upload.aspx");
            client.CopyMemberFile(memberNumber, Path.GetFileName(file), filebytes);                    
        }

        client.LogEvent("Completed service call from Upload.aspx");
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.StackTrace);

        client.LogEvent("Upload.aspx Error: " + ex.Message + ex.StackTrace);

        StatusLabel.Text = "Upload status: The file could not be uploaded. The following error occured: " + ex.Message;
    }
    finally
    {
        client.LogEvent("Finishing up");
    }
}

1 个答案:

答案 0 :(得分:0)

查看服务的配置文件,您使用的是.NET 4.0并且未指定任何绑定,因此您将收到basicHttpBinding的默认设置。如上面的评论所示,请更新您的服务的配置文件,如下所示:

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior>
        <serviceMetadata httpGetEnabled="true"/>
        <serviceDebug includeExceptionDetailInFaults="true"/>
      </behavior>
    </serviceBehaviors>
  </behaviors>
  <bindings>
    <basicHttpBinding>
      <binding name="BasicHttpBinding_IMembershipApplications" 
                     closeTimeout="00:01:00"
                     openTimeout="00:01:00" 
                     receiveTimeout="00:10:00" 
                     sendTimeout="00:01:00"
                     allowCookies="false" 
                     bypassProxyOnLocal="false" 
                     hostNameComparisonMode="StrongWildcard"
                     maxBufferSize="2147483647" 
                     maxBufferPoolSize="2147483647" 
                     maxReceivedMessageSize="2147483647"
                     messageEncoding="Text" 
                     textEncoding="utf-8" 
                     transferMode="Buffered"
                     useDefaultWebProxy="true">
        <readerQuotas maxDepth="128" 
                      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>
  <services>
    <service name="YourServiceName">
      <endpoint address="" 
                binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_IMembershipApplications" 
                contract="YourFullyQualifiedContractName" />
    </service>
  </services>
  <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

这将告诉WCF将您的设置用于basicHttpBinding而不是.NET默认设置。

或者,您可以省略绑定定义上的name属性,WCF将其用作配置文件处理的所有服务的默认绑定(如果您有多个)。

如果这没有帮助,或者您现在遇到其他错误,请告诉我们,我们会从那里接受。