Member 12759885 Ответов: 1

Как отправить файл для данного универсального обработчика


У меня есть 2 сервера, между ними нет связи, один (а) имеет формы ввода данных, и я должен переместить эти данные на второй сервер (Б).

Я отправляю данные из (А) в виде csv-файла обработчику на сервере(б). Я использовал следующий код для отправки данных, но файл не получает в обработчике. контексте.Запрос.Файлы.Count всегда < 0. (Hanldler работает нормально, я проверил то же самое с загрузчиком файлов). что было бы неправильно в приведенном ниже коде? или любое другое предложение по передаче данных?

Что я уже пробовал:

const string FILE_PATH = "C:\\Docs\\SampleCV.csv";
    const string FILE_NAME = "SampleCV";
    string UPLOADER_URI = string.Format("http://GIC1493-DSK1:82/ExportData.ashx?FILE_NAME={0}", FILE_NAME);
    var httpRequest = WebRequest.Create(UPLOADER_URI) as HttpWebRequest;
    using (Stream stream = File.OpenRead(FILE_PATH))
    {
        httpRequest.Method = "POST";

        //stream.Seek(0, SeekOrigin.Begin);
        //stream.CopyTo(httpRequest.GetRequestStream());
        //var httpResponse = httpRequest.GetResponse();
        //StreamReader reader = new StreamReader(httpResponse.GetResponseStream());
        //var responseString = reader.ReadToEnd();
        //lblMsg.Text = "Posted to server";            

        Stream webStream = null;
        try
        {
            if (stream != null && stream.Length > 0)
            {
                long length = stream.Length;
                httpRequest.ContentLength = length;
                webStream = httpRequest.GetRequestStream();
                stream.CopyTo(webStream);
            }
        }
        finally
        {
            if (null != webStream)
            {
                stream.Flush();
                stream.Close();
                webStream.Flush();
                webStream.Close();
            }
        }
        using (HttpWebResponse response = HttpWebResponse)httpRequest.GetResponse())
        {
            StreamReader reader = new StreamReader(response.GetResponseStream());
            var responseString = reader.ReadToEnd();
            lblMsg.Text = "Posted to server. Response is : " + responseString; ;
        }

1 Ответов

Рейтинг:
11

Richard Deeming

Ваш куратор ожидает multipart/formdata[^] запрос, но ваш код просто отправляет необработанные байты файла.

Вам нужно построить правильный запрос для передачи файла:

public static class Extensions
{
    public static void PrepareFileUpload(this WebRequest request, string fieldName, Stream fileStream, string fileName, string contentType)
    {
        string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
        request.ContentType = "multipart/form-data; boundary=" + boundary;
        request.Method = "POST";
        
        using (var stream = request.GetRequestStream())
        using (var writer = new StreamWriter(stream, System.Text.Encoding.ASCII))
        {
            writer.WriteLine();
            writer.WriteLine("--{0}", boundary);
            writer.WriteLine("Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"", fieldName, fileName);
            writer.WriteLine("Content-Type: {0}", contentType);
            writer.WriteLine();
            writer.Flush();
            
            fileStream.CopyTo(stream);
            
            writer.WriteLine();
            writer.WriteLine("--{0}--", boundary);
        }
    }
}

...

var httpRequest = WebRequest.Create(UPLOADER_URI);
httpRequest.PrepareFileUpload("fieldName", stream, "MyFile.csv", "text/csv");

using (var response = httpRequest.GetResponse())
using (var reader = new StreamReader(response.GetResponseStream()))
{
    var responseString = reader.ReadToEnd();
    lblMsg.Text = "Posted to server. Response is : " + responseString;
} 


Кроме того, если вы всегда загружаете файл, хранящийся в файловой системе сервера а, вы можете использовать класс WebClient[^]:
using (var client = new WebClient())
{
    byte[] response = client.UploadFile(UPLOADER_URI, FILE_PATH);
    string responseString = Encoding.UTF8.GetString(response);
    lblMsg.Text = "Posted to server. Response is : " + responseString;
}


Или, если вы используете .NET 4.0 или выше, вы можете использовать класс HttpClient[^]:
private static readonly HttpClient Client = new HttpClient();
...
using (var content = new MultipartFormDataContent())
{
    content.Add(new StreamContent(stream), "fieldName", "MyFile.csv");
    
    using (var response = await Client.PostAsync(UPLOADER_URI, content))
    {
        response.EnsureSuccessStatusCode();
        string responseString = await response.Content.ReadAsStringAsync();
        lblMsg.Text = "Posted to server. Response is : " + responseString;
    }
}

NB: Вам нужно будет сделать свой код async использовать это.