WebClient UploadFile и хранение на сервере - PullRequest
1 голос
/ 12 марта 2019

У меня есть небольшое консольное приложение, которое загружает файл в мой веб-сервис, оба работают локально на моем компьютере с Windows 10.

Код консольного приложения для загрузки файла в веб-сервис:

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

Затем код веб-службы копирует поток в новый файл:

[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;
}

Похоже, что файл загружен нормально и прекрасно хранится в веб-сервисе без проблем.

Когда я просматриваю загруженную копию (в данный момент копируемую в другое место на моем компьютере) и пытаюсь открыть файл, он не открывается. Когда я сравниваю метаданные исходного файла с загруженным файлом, все метаданные исчезают в новом файле.

  • EXE больше не открывается.
  • JPG не открывается с помощью Windows Photo Viewer или Paint. Только в фотошопе.
  • PNG, похоже, вообще не имеет проблем.

Что мне не хватает? Я попытался сначала прочитать поток файлов в MemoryStream, а затем в файл, все еще сохраняет файл с правильным размером / длиной содержимого, но без метаданных:

enter image description here

1 Ответ

1 голос
/ 12 марта 2019

Вы пытаетесь сохранить поток файла, который содержит байты границы.

Посмотрите на исходный код WebClient UploadFileAsync здесь: https://referencesource.microsoft.com/#system/net/System/Net/webclient.cs Линия 2389

Попробуйте следующее, загрузив файл чисто:

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();
}
...