简体   繁体   English

WCF服务(413)请求实体中的文件上传过大

[英]File upload in WCF Service (413) Request Entity Too Large

I'm trying to implement file upload into my WCF Service in asp .net C# 我正在尝试在ASP .NET C#中将文件上传到我的WCF服务中

Here is the code in WCF Server for File uploading. 这是WCF Server中用于文件上传的代码。

 public void FileUpload(string fileName, Stream fileStream)
       {
           FileStream fileToupload = new FileStream("D:\\FileUpload\\" + fileName, FileMode.Create);

        //   byte[] bytearray = new byte[10000];
           byte[] bytearray = new byte[1000];
           int bytesRead, totalBytesRead = 0;
           do
           {
               bytesRead = fileStream.Read(bytearray, 0, bytearray.Length);
               totalBytesRead += bytesRead;
               if(bytesRead > 0)
               fileToupload.Write(bytearray, 0, bytearray.Length);

           } while (bytesRead > 0);

         //  fileToupload.Write(bytearray, 0, bytearray.Length);
           fileToupload.Close();
           fileToupload.Dispose();



       }

Here is the code for Client to upload a File: (Fixed Byte Array Size) 这是客户端上传文件的代码:( 固定字节数组大小)

protected void bUpload_Click(object sender, EventArgs e)
{
    byte[] bytearray = null;
    Stream stream;
    string fileName = "";
    //throw new NotImplementedException();
    if (FileUpload1.HasFile)
    {
        fileName = FileUpload1.FileName;
        stream = FileUpload1.FileContent;
        stream.Seek(0, SeekOrigin.Begin);
        bytearray = new byte[stream.Length];
        int count = 0;
        while (count < stream.Length)
        {
            bytearray[count++] = Convert.ToByte(stream.ReadByte());
        }

    }

    string baseAddress = "http://localhost/WCFService/Service1.svc/FileUpload/";

    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(baseAddress + fileName);
    request.Method = "POST";
    request.ContentType = "text/plain";
    Stream serverStream = request.GetRequestStream();
    serverStream.Write(bytearray, 0, bytearray.Length);
    serverStream.Close();
    try
    {
        using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
        {
            int statusCode = (int)response.StatusCode;
            System.Diagnostics.Debug.WriteLine("statusCode: " + statusCode);

            StreamReader reader = new StreamReader(response.GetResponseStream());
            System.Diagnostics.Debug.WriteLine("reader: " + reader.ToString());

        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine("--- EXCEPTION ---");
        ex.ToString();
    }
}

This is working good with a small size file, When I tried with bigger size files I changed fixed size byte array to a dynamic byte array Writing to stream. 对于较小的文件,这是很好的方法,当我尝试使用较大的文件时,我将固定大小的字节数组更改为动态字节数组。 Here is updated code: (chunks of 1024 bytes of Byte array used to Send data) 这是更新的代码:( 用于发送数据的Byte数组的1024字节块)

        request.Method = "POST";
        request.ContentType = "text/plain";
       // Stream serverStream = request.GetRequestStream();

        if (FileUpload1.HasFile)
        {
            fileName = FileUpload1.FileName;
            stream = FileUpload1.FileContent;
            stream.Seek(0, SeekOrigin.Begin);
            bytearray = new byte[1024];//stream.Length];


        }
        int TbyteCount = 0;
        Stream requestStream = request.GetRequestStream();

            int bufferSize = 1024;
            byte[] buffer = new byte[bufferSize];
            int byteCount = 0;
            while ((byteCount = stream.Read(buffer, 0, bufferSize)) > 0)
            {
                TbyteCount = TbyteCount + byteCount; 
                requestStream.Write(buffer, 0, byteCount);
            }

            requestStream.Close();


        try
        {
            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
            {
                int statusCode = (int)response.StatusCode;
                System.Diagnostics.Debug.WriteLine("statusCode: " + statusCode);

                StreamReader reader = new StreamReader(response.GetResponseStream());
                System.Diagnostics.Debug.WriteLine("reader: " + reader.ToString());

            }
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine("--- EXCEPTION ---");
            ex.ToString();
        }
    }

But While reading response I get Exception The remote server returned an error: (413) Request Entity Too Large. 但是在读取响应时,我得到异常远程服务器返回错误:(413)请求实体太大。

Am I doing correct with writing multiple times in request stream !? 我在请求流中多次写入是否正确!?

I used a file size 22.4 KB, it is successfully uploaded using 1st code (fixed size array) If I split file size in multiples of 1024 bytes and tried to send then there is a problem. 我使用的文件大小为22.4 KB,使用第一个代码(固定大小的数组)已成功上传。如果我将文件大小分割为1024字节的倍数并尝试发送,则出现问题。

Web.config file Web.config文件

<?xml version="1.0"?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
  </appSettings>
  <system.web>
    <compilation debug="true"/>
  </system.web>
  <system.serviceModel>
    <services>
      <service name="WcfServiceApp.Service1" behaviorConfiguration="ServiceBehavior">
        <endpoint address="" binding="webHttpBinding" contract="WcfServiceApp.IService1" behaviorConfiguration="webBehaviour"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:50327/Service1.svc"/>
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <!-- To avoid disclosing metadata information, set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <!-- 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="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webBehaviour">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <!--<protocolMapping>
      <add binding="basicHttpsBinding" scheme="https"/>
    </protocolMapping>-->
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
  </system.serviceModel>
  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*"/>
        <add name="Access-Control-Allow-Headers" value="Content-Type, Accept"/>
      </customHeaders>
    </httpProtocol>
    <directoryBrowse enabled="true"/>
  </system.webServer>
</configuration>

When you try to transfer big serialized object with some structure this problem usually caused by leak of maxItemsInObjectGraph in configuration. 当您尝试传输具有某些结构的大序列化对象时 ,通常会由于配置中maxItemsInObjectGraph的泄漏而导致此问题。 See my answer here 在这里查看我的答案

But in your case you try just transfer simple data file as stream of bytes. 但是在您的情况下,您尝试仅将简单的数据文件作为字节流传输。 To do that via webHttpBinding you should specify proper service contract, which accepts only stream message as input. 要通过webHttpBinding做到这一点,您应该指定适当的服务协定,该协定接受流消息作为输入。 All additional stuff like filenames you can specify as headers in message contract (actually maybe you way with filename as parameter from URI will also work). 您可以在消息协定中将所有其他内容(例如文件名)指定为标头(实际上,也许您也可以使用URI中的文件名作为参数)。 Then you must set TransferMode = TransferMode.Streamed for your binding. 然后,必须为绑定设置TransferMode = TransferMode.Streamed Some code example is here One more with config samples is here . 这里有一些代码示例,这里 还有配置示例

Keywords for additional googling is webhttpbinding streaming 额外搜寻的关键字是webhttpbinding流

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM