上传文件的WCF服务(413)请求实体过大 [英] File upload in WCF Service (413) Request Entity Too Large

查看:949
本文介绍了上传文件的WCF服务(413)请求实体过大的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现文件上传到我的WCF服务在ASP.NET的C#

下面是WCF服务器的code用于文件上传

 公共无效文件上传(字符串文件名,流FILESTREAM)
       {
           的FileStream fileToupload =新的FileStream(D:\\\\ \\\\的FileUpload+文件名,FileMode.Create);        //字节[]字节组=新的字节[10000]
           字节[]字节组=新的字节[1000];
           INT读取动作,totalBytesRead = 0;
           做
           {
               读取动作= fileStream.Read(字节数组,0,bytearray.Length);
               totalBytesRead + =读取动作;
               如果(读取动作大于0)
               fileToupload.Write(字节数组,0,bytearray.Length);           }而(读取动作大于0);         // fileToupload.Write(字节数组,0,bytearray.Length);
           fileToupload.C​​lose();
           fileToupload.Dispose();       }

下面是code客户端上传文件:(固定字节数组大小)

 保护无效bUpload_Click(对象发件人,EventArgs的发送)
{
    字节[]字节组= NULL;
    流流;
    字符串文件名=;
    //抛出新NotImplementedException();
    如果(FileUpload1.HasFile)
    {
        文件名= FileUpload1.FileName;
        流= FileUpload1.FileContent;
        stream.Seek(0,SeekOrigin.Begin);
        字节组=新的字节[stream.Length]
        诠释计数= 0;
        而(COUNT< stream.Length)
        {
            ByteArray的[统计++] = Convert.ToByte(stream.ReadByte());
        }    }    字符串baseAddress =HTTP://localhost/WCFService/Service1.svc/FileUpload/    HttpWebRequest的要求=(HttpWebRequest的)HttpWebRequest.Create(baseAddress +文件名);
    request.Method =POST;
    request.ContentType =text / plain的;
    流serverStream = request.GetRequestStream();
    serverStream.Write(字节数组,0,bytearray.Length);
    serverStream.Close();
    尝试
    {
        使用(HttpWebResponse响应= request.GetResponse()作为HttpWebResponse)
        {
            INT状态code =(int)的response.Status code;
            System.Diagnostics.Debug.WriteLine(状态code:+状态code);            StreamReader的读者=新的StreamReader(response.GetResponseStream());
            System.Diagnostics.Debug.WriteLine(读者+ reader.ToString());        }
    }
    赶上(异常前)
    {
        System.Diagnostics.Debug.WriteLine(--- EXCEPTION ---);
        ex.ToString();
    }
}

这是工作好,具有体积小文件,当我和大大小的文件试过
我改变了固定大小的字节数组到动态的字节数组写入流。
下面是更新code:(1024字节的字节数组用于传送数据块)

  request.Method =POST;
        request.ContentType =text / plain的;
       //流serverStream = request.GetRequestStream();        如果(FileUpload1.HasFile)
        {
            文件名= FileUpload1.FileName;
            流= FileUpload1.FileContent;
            stream.Seek(0,SeekOrigin.Begin);
            字节组=新的字节[1024]; /​​/ stream.Length]。
        }
        INT TbyteCount = 0;
        流requestStream = request.GetRequestStream();            INT缓冲区大小= 1024;
            字节[]缓冲区=新的字节[缓冲区大小]
            INT BYTECOUNT = 0;
            而((BYTECOUNT = stream.Read(缓冲液,0,缓冲区大小))大于0)
            {
                TbyteCount = TbyteCount + BYTECOUNT;
                requestStream.Write(缓冲液,0,BYTECOUNT);
            }            requestStream.Close();
        尝试
        {
            使用(HttpWebResponse响应= request.GetResponse()作为HttpWebResponse)
            {
                INT状态code =(int)的response.Status code;
                System.Diagnostics.Debug.WriteLine(状态code:+状态code);                StreamReader的读者=新的StreamReader(response.GetResponseStream());
                System.Diagnostics.Debug.WriteLine(读者+ reader.ToString());            }
        }
        赶上(异常前)
        {
            System.Diagnostics.Debug.WriteLine(--- EXCEPTION ---);
            ex.ToString();
        }
    }

但是在读的响应,我得到异常
远程服务器返回错误:(413)请求实体过大

我做正确的,在请求流写入多次!?

我用了文件大小22.4 KB,它使用1 code(固定大小的数组)成功上传
如果我在1024字节的倍数分割文件的大小,并试图发送再有是一个问题。

Web.config文件

 <?XML版本=1.0&GT?;
<结构>
  <&的appSettings GT;
    <添加键=ASPNET:UseTaskFriendlySynchronizationContextVALUE =真/>
  < /的appSettings>
  <&的System.Web GT;
    <编译调试=真/>
  < /system.web>
  < system.serviceModel>
    <服务和GT;
      <服务名称=WcfServiceApp.Service1behaviorConfiguration =ServiceBehavior>
        <端点地址=绑定=的WebHttpBinding合同=WcfServiceApp.IService1behaviorConfiguration =webBehaviour/>
        <主机>
          < baseAddresses>
            <添加baseAddress =HTTP://本地主机:50327 / Service1.svc/>
          < / baseAddresses>
        < /主机>
      < /服务>
    < /服务>
    <&行为GT;
      < serviceBehaviors>
        <行为NAME =ServiceBehavior>
          <! - 为了避免泄露的元数据信息,在部署之前设置以下为false值 - >
          < serviceMetadata httpGetEnabled =真httpsGetEnabled =真/>
          <! - 要接收故障中的异常细节进行调试,下面设置为true值。设置为false部署之前,以避免泄露异常信息 - >
          < serviceDebug includeExceptionDetailInFaults =FALSE/>
        < /行为>
      < / serviceBehaviors>
      < endpointBehaviors>
        <行为NAME =webBehaviour>
          < webHttp />
        < /行为>
      < / endpointBehaviors>
    < /行为>
    <! - < protocolMapping>
      <添加绑定=basicHttpsBinding计划=HTTPS/>
    &所述; / protocolMapping&GT - →;
    < serviceHostingEnvironment aspNetCompatibilityEnabled =真multipleSiteBindingsEnabled =真/>
  < /system.serviceModel>
  < system.webServer>
    < httpProtocol>
      < customHeaders>
        <添加名称=访问控制允许来源VALUE =*/>
        <添加名称=访问控制 - 允许 - 头VALUE =Content-Type的,接受/>
      < / customHeaders>
    < / httpProtocol>
    < directoryBrowse启用=真/>
  < /system.webServer>
< /结构>


解决方案

当您尝试传输大系列化的目标有一定的结构这个问题通常是由 maxItemsInObjectGraph <泄漏引起/ code>的配置。看到我的<一个href=\"http://stackoverflow.com/questions/32866701/unexpected-response-returned-by-wcf-service-413-request-entity-too-large/\">answer这里

但是,在你的情况您尝试只传输简单的数据文件的字节流。要做到这一点通过的WebHttpBinding 您应该指定适当的服务合同,它接受的流消息作为输入。所有额外的东西,如文件名,你可以指定在消息协定头(其实也许你的方式与文件名作为参数的URI也将工作)。然后,你必须将 TransferMode = TransferMode.Streamed 为您绑定。有些<一个href=\"http://social.technet.microsoft.com/wiki/contents/articles/1140.wcf-streaming-large-data-files-using-webhttpbinding.aspx\"相对=nofollow> code例子是这里还有一个的与配置的样本是这里

更多的谷歌搜索关键词为的WebHttpBinding流

I'm trying to implement file upload into my WCF Service in asp .net C#

Here is the code in WCF Server for File uploading.

 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)

        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.

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.

Web.config file

<?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. 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. 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). Then you must set TransferMode = TransferMode.Streamed for your binding. Some code example is here One more with config samples is here.

Keywords for additional googling is webhttpbinding streaming

这篇关于上传文件的WCF服务(413)请求实体过大的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆