Pierre
Pierre

Reputation: 9052

WebClient UploadFile and Storing on the server

I have a small console app which uploads a file to my web service, both running locally on my Windows 10 machine.

The console app code to upload a file to the web service:

using (var client = new WebClient())
{
    client.UploadProgressChanged += ...;
    client.UploadFileCompleted += ...;
    await client.UploadFileTaskAsync(wsURL, "POST", FilePath);
}

Then the web service code, copies stream into a new file:

[OperationContract]
[WebInvoke(Method = "POST")]
public bool Upload(Stream fs)
{
    using (var file = File.Open(NewFilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
    {
        fs.CopyTo(file);
    }

    return true;
}

It looks like the file is uploaded fine and it is storing perfectly fine on the web service without issues.

When I browse to the uploaded copy (basically copied to another location on my machine at this point) and try to open the file, it won't open. When I compare the meta data of the original file to the uploaded file, the metadata is all gone in the new file.

What am I missing? I have tried to read the filestream into MemoryStream first and then to the file, still saves the file with the correct size/content length but without metadata:

enter image description here

Upvotes: 1

Views: 1298

Answers (1)

Cliff
Cliff

Reputation: 66

You are trying to store a stream of a file which contains boundary bytes.

Look at the source code of WebClient UploadFileAsync here: https://referencesource.microsoft.com/#system/net/System/Net/webclient.cs Line 2389

Try the following, uploading the file cleanly:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.ServicePoint.Expect100Continue = false;
request.Method = "POST";
request.ContentType = MimeMapping.GetMimeMapping(FilePath);

using (FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
using(Stream requestStream = request.GetRequestStream())
{
    byte[] buffer = new byte[1024 * 4];
    int bytesLeft = 0;
    while((bytesLeft = fs.Read(buffer, 0, buffer.Length)) > 0)
    {
        requestStream.Write(buffer, 0, bytesLeft);
    }
}

using (var response = (HttpWebResponse)request.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var sr = new StreamReader(responseStream))
{
    var responseString = sr.ReadToEnd();
}

Upvotes: 1

Related Questions