The remote server returned an error: (400) Bad Request - uploading less 2MB file size?
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">
Comments
-
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.
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 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 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 about 12 yearsJust to be clear, you can upload files larger than 10MB, but the value I pasted above would limit it to 10MB
-
fiberOptics about 12 yearsI'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 about 12 yearsHey @ryan, did you use the server code that I pasted. The one that you originally posted can never grow beyond 10KB
-
fiberOptics about 12 yearsPlease see the edited question. I've used your second suggestion. The code under "However, if you move..." doesn't eliminate [NUL] data.
-
Tung about 12 years