Smart File API для загрузки файлов - PullRequest
0 голосов
/ 13 июня 2018

Я ненавижу этот API .... В документации говорится:

POST / api / 2 / path / data / Documents / HTTP / 1.1

Content-Type: multipart/ form-data

Content-Length: длина тела запроса здесь

данные из нескольких частей здесь

Итак, я создал это:

    public async Task<bool> UploadAsync(string path, string fileName, byte[] data)
    {
        EnforceBasicAuthentication();
        var byteContent = new ByteArrayContent(data);
        byteContent.Headers.Remove("Content-Type");
        byteContent.Headers.Add("Content-Type", "multipart/form-data");
        byteContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
        {
            FileName = fileName,
            Name = "file"
        };
        var form = new MultipartFormDataContent
        {
            byteContent
        };
        var response = await _httpClient.PostAsync($"{_config.FtpUrl}/path/data/{_config.FtpPath}/{path}", form);
        response.EnsureSuccessStatusCode();
        return true;
    }

Но каждый раз, когда я запускаю его, я получаю ошибку 400 неверных запросов.Это не говорит ничего, кроме этого.Глядя на мой код, есть ли что-то, что выглядит неправильно?


Я пробовал несколько решений, и ни одно из них, похоже, не работает.В настоящее время у меня есть это:

public async Task<bool> UploadAsync(string path, string fileName, byte[] data)
{
    EnforceBasicAuthentication();

    var boundary = "--------------------------" + DateTime.Now.Ticks.ToString("x");
    var bytesContent = new ByteArrayContent(data);
    var form = new MultipartFormDataContent();

    form.Add(bytesContent, "file", fileName);
    form.Headers.Remove("Content-Type");
    form.Headers.TryAddWithoutValidation("Content-Type", $"multipart/form-data; boundary= { boundary }");
    bytesContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");

    var response = await _httpClient.PostAsync($"{_config.FtpUrl}/path/data/{_config.FtpPath}/{path}", form);
    response.EnsureSuccessStatusCode();
    return true;
}

Но все равно выдает ошибку 400.Я настроил Fiddler и провел тест в почтальоне.Тест в почтальоне работал нормально.Вот запрос в фиддлере:

POST https://app.smartfile.com/api/2/path/data/eOrdering/GRE017 HTTP / 1.1

cache-control: no-cache

Postman-Token: 8359aae8-f4e2-4864-b81a-0169fe3f2b62

Авторизация: Basic bleh

Пользователь-агент: PostmanRuntime / 7.1.1

Принимать: /

Хост: app.smartfile.com

cookie: csrftoken = rsDaPbfwG070rwBFlhIWVvULcAqGW0GB;

sessionid = a744788776bfef3c44faf6eb5e2a2931

принять кодировку: gzip, deflate

тип содержимого: multipart / form-data;border = -------------------------- 606952503302468487113354

длина содержимого: 334

Подключение: закрыть

---------------------------- 606952503302468487113354

Content-Disposition: form-data;имя = "";filename = "S200-220311-20180606095501.ord"

Content-Type: application / octet-stream

274 274/1 | PAULA | 00220311 | STD ||| ASAP

1 | 23133 | 1313 131302 4,00 | C | 3,65 ||| 12/06/18

---------------------------- 606952503302468487113354 -

И это тот, который сгенерирован моим кодом:

POST https://app.smartfile.com/api/2/path/data/eOrdering/GRE017 HTTP / 1.1

Авторизация: Basic blah

Content-Type: multipart / form-data;border = -------------------------- 8d5d140cf824278

Хост: app.smartfile.com

Cookie:csrftoken = NYOgu61I6ddqBgudQEhWNr27fJUEQFi3;

sessionid = 6994ad9254ebc46e0611e6ac308d6c55

Длина содержимого: 375

- 52343329-f101-43a2-b4bb-bfa9a4073f6e

Форма данных-расположение:;имя = файл;имя файла = 3c3f1596-707b-4725-9766-25faf6124a35.rsl;имя файла * = utf-8''3c3f1596-707b-4725-9766-25faf6124a35.rsl

Тип содержимого: application / octet-stream

Fail | "Номер вопроса о цене недействителен, долженбыть больше 0 "|

1 | 23133 | 01/01/0001 00: 00: 00 | 0 | 0

- 52343329-f101-43a2-b4bb-bfa9a4073f6e -

Я до сих пор понятия не имею, почему он выходит из строя: (

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

Итак, я понял это, потратив на это целую вечность.Есть две проблемы, которые необходимо решить.Первым был двойной fileName (в котором также не было двойных кавычек), а вторым была граница .... В конце я изменил свой код, чтобы он выглядел так:

public async Task<bool> UploadAsync(string path, string fileName, byte[] data)
{
    EnforceBasicAuthentication();
    var bytesContent = new ByteArrayContent(data);
    bytesContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream");
    bytesContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
    {
        Name = "\"file\"",
        FileName = $"\"{fileName}\""
    };
    var formData = new MultipartFormDataContent { bytesContent };
    var boundary = formData.Headers.ContentType.Parameters.First(o => o.Name == "boundary");
    boundary.Value = boundary.Value.Replace("\"", string.Empty);
    var response = await _httpClient.PostAsync($"{_config.FtpUrl}/path/data/{_config.FtpPath}/{path}", formData);
    response.EnsureSuccessStatusCode();
    return true;
}

Как вы можете видеть, для ContentDisposition я добавил имя и имя файла (с \ "из-за ошибки ....), а для типа контента FormData мне пришлось удалить лишниедвойные кавычки.

Действительно раздражает, но, наконец, работает ....

0 голосов
/ 13 июня 2018

Попробуйте свои байтовые данные в var content = new ByteArrayContent (filedata);и передать содержимое в PostAsync примерно так:

var content = new ByteArrayContent(data);
var ApiRequest = client.PostAsync(apiUrl, content);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...