The remote server returned an error: (400) Bad Request - uploading less 2MB file size?

11,568

I think the reason you're seeing nulls is because of the following line. You're initializing a buffer, but you're probably not filling that entire buffer:

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

It should instead be:

fileToupload.Write(bytearray, 0, totalBytesRead);
fileToupload.Close();
fileToupload.Dispose();

You're also always overwriting your buffer within each loop iteration:

fileStream.Read(bytearray, 0, bytearray.Length)`.  

When you probably want this, as it continues to fill the rest of your buffer:

fileStream.Read(bytearray, totalBytesRead, byteArray.Length - totalBytesRead);

However, if you move the code that writes to the file inside your loop, then you will only have to make minimal changes to your existing code:

int bytesRead, totalBytesRead = 0;
do
{
    bytesRead = fileStream.Read(bytearray, 0, bytearray.Length);
    if (bytesRead > 0)
    {
        fileToupload.Write(bytearray, 0, bytesRead);
    }
} while (bytesRead > 0);

You will receive 400 if you try to send more data than the MaxReceivedMessageSize. Adjust it accordingly:

<binding maxReceivedMessageSize="10485760">
Share:
11,568
fiberOptics
Author by

fiberOptics

learner

Updated on June 22, 2022

Comments

  • fiberOptics
    fiberOptics almost 2 years

    The file succeed to upload when it is 2KB or lower in size. The main reason why I use streaming is to be able to upload file up to at least 1 GB. But when I try to upload file with less 1MB size, I get bad request. It is my first time to deal with downloading and uploading process, so I can't easily find the cause of error.

    Testing part:

    private void button24_Click(object sender, EventArgs e)
    {
        try
        {
            OpenFileDialog openfile = new OpenFileDialog();
            if (openfile.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                string port = "3445";
                byte[] fileStream;
                using (FileStream fs = new FileStream(openfile.FileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    fileStream = new byte[fs.Length];
                    fs.Read(fileStream, 0, (int)fs.Length);
                    fs.Close();
                    fs.Dispose();
                }
    
                string baseAddress = "http://localhost:" + port + "/File/AddStream?fileID=9";
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(baseAddress);
                request.Method = "POST";
                request.ContentType = "text/plain";
                //request.ContentType = "application/octet-stream";
                Stream serverStream = request.GetRequestStream();
                serverStream.Write(fileStream, 0, fileStream.Length);
                serverStream.Close();
                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    int statusCode = (int)response.StatusCode;
                    StreamReader reader = new StreamReader(response.GetResponseStream());
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }  
    

    Service:

    [WebInvoke(UriTemplate = "AddStream?fileID={fileID}", Method = "POST", BodyStyle = WebMessageBodyStyle.Bare)]
    public bool AddStream(long fileID, System.IO.Stream fileStream)
    {
        ClasslLogic.FileComponent svc = new ClasslLogic.FileComponent();
        return svc.AddStream(fileID, fileStream);
    }  
    

    Server code for streaming:

    namespace ClasslLogic
    {
        public class StreamObject : IStreamObject
        {
            public bool UploadFile(string filename, Stream fileStream)
            {
                try
                {
                    FileStream fileToupload = new FileStream(filename, FileMode.Create);
                    byte[] bytearray = new byte[10000];
                    int bytesRead, totalBytesRead = 0;
                    do
                    {
                        bytesRead = fileStream.Read(bytearray, 0, bytearray.Length);
                        totalBytesRead += bytesRead;
                    } while (bytesRead > 0);
    
                    fileToupload.Write(bytearray, 0, bytearray.Length);
                    fileToupload.Close();
                    fileToupload.Dispose();
                }
                catch (Exception ex) { throw new Exception(ex.Message); }
                return true;
            }
        }
    }  
    

    Web config:

    <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding>
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="2097152" maxBytesPerRead="4096" maxNameTableCharCount="2097152" />
          <security mode="None" />
        </binding>
        <binding name="ClassLogicBasicTransfer" closeTimeout="00:05:00" openTimeout="00:05:00" receiveTimeout="00:15:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="67108864" maxReceivedMessageSize="67108864" messageEncoding="Mtom" textEncoding="utf-8" useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="67108864" maxBytesPerRead="4096" maxNameTableCharCount="67108864" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
        <binding name="BaseLogicWSHTTP">
          <security mode="None" />
        </binding>
        <binding name="BaseLogicWSHTTPSec" />
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="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="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
    </system.serviceModel>
    

    I'm not sure if this affects the streaming function, because I'm using WCF4.0 rest template which config is dependent in Global.asax.

    One more thing is this, whether I run the service and passing a stream or not, the created file always contain this thing.

    enter image description here

    How could I remove the "NUL" data?

    Thanks in advance.

    Edit

    public bool UploadFile(string filename, Stream fileStream)
            {
                try
                {
                    FileStream fileToupload = new FileStream(filename, FileMode.Create);
                    byte[] bytearray = new byte[10000];
                    int bytesRead, totalBytesRead = 0;
                    do
                    {
                        bytesRead = fileStream.Read(bytearray, totalBytesRead, bytearray.Length - totalBytesRead);
                        totalBytesRead += bytesRead;
    
                    } while (bytesRead > 0);
    
                    fileToupload.Write(bytearray, 0, totalBytesRead);
                    fileToupload.Close();
                    fileToupload.Dispose();
                }
                catch (Exception ex) { throw new Exception(ex.Message); }
                return true;
            }
    
  • fiberOptics
    fiberOptics about 12 years
    +1 nulls has been remove. But still having bad request when file size is up to 1MB or more. Do you have any idea for this? thanks
  • Tung
    Tung about 12 years
    @ryan, add maxReceivedMessageSize="10485760" to the Binding that you are using in your endpoint. This will allow you to upload files of up to 10MB
  • Tung
    Tung about 12 years
    Just to be clear, you can upload files larger than 10MB, but the value I pasted above would limit it to 10MB
  • fiberOptics
    fiberOptics about 12 years
    I'm sorry for this last question. The file I'm uploading is 800KB, but it only creates the file for 10KB, maxReceivedMessageSize="10485760". What's wrong with this? thanks
  • Tung
    Tung about 12 years
    Hey @ryan, did you use the server code that I pasted. The one that you originally posted can never grow beyond 10KB
  • fiberOptics
    fiberOptics about 12 years
    Please see the edited question. I've used your second suggestion. The code under "However, if you move..." doesn't eliminate [NUL] data.
  • Tung
    Tung about 12 years