Неправильный POST запрос с JSON данными

135
21 ноября 2018, 01:00

Реализовываю API запросы на биржу криптовалют BTC-Alpha. В частности вот такой запрос, который позволяет приобретать на бирже разные валюты.

Вот моя реализация:

Вызов метода.

public OrderCreationResponseDTO CreateOrder(OrderCreationDTO dto)
    => POST<OrderCreationResponseDTO>(dto,
                                      "https://btc-alpha.com/api/v1/order",
                                      GetAuthHeaders(JsonConvert.SerializeObject(dto)));

Как вы видите, вызывается метод POST, который возвращает нам непонятную DTO-ху, а внутрь этого метода передаётся ещё и метод GetAuthHeaders, который в свою очередь, принимает JSON строку.

POST<>

private protected T POST<T>(object jsonDTO, string url, string[] headers = null)
{
    var req = WebRequest.Create(url);
    req.Method = "POST";
    if (headers != null)
        for (int i = 0; i < headers.Length; i++)
            req.Headers.Add(headers[i]);
    using (var dataStream = new StreamWriter(req.GetRequestStream(), Encoding.UTF8))
        dataStream.Write(JsonConvert.SerializeObject(jsonDTO));
    var response = (HttpWebResponse)req.GetResponse(); //Вот тут всё падает
    var responseStream = response.GetResponseStream();
    return JsonConvert.DeserializeObject<T>(new StreamReader(responseStream).ReadToEnd());
}

GetAuthHeaders | Этот метод делает нам правильные заголовки для запроса. Реализовано согласно документации API.

public string ApiKey { get; set; }
public string UserSecret { get; set; } //Это я для наглядности добавил
private string[] GetAuthHeaders(string postData = null)
{
    if (postData == null) postData = string.Empty;
    else //На костыль ниже не обращайте внимания, он рабочий :)
    {
        postData = postData.Replace("{", "");
        postData = postData.Replace("}", "");
        postData = postData.Replace("\"", "");
        postData = postData.Replace(":", "=");
        var args = postData.Split(',');
        Array.Sort(args, (x, y) => string.Compare(x, y));
        postData = args[0];
        for (int i = 1; i < args.Length; i++)
            postData += "&" + args[i];
    }
    string sign = BitConverter.ToString(new HMACSHA256(Encoding.ASCII.GetBytes(UserSecret))
        .ComputeHash(Encoding.ASCII.GetBytes(ApiKey + postData))).Replace("-", "").ToLower();
    return new string[3]
    {
        "X-KEY:" + ApiKey,
        "X-SIGN:" + sign,
        "X-NONCE:" + new DateTimeOffset(DateTime.Now).ToUnixTimeMilliseconds()
    };
}

OrderCreationDTO | Собственно те данные которые я хочу отправить

public sealed class OrderCreationDTO
{
    [JsonProperty("amount")]
    public string Amount { get; set; }
    [JsonProperty("pair")]
    public string Pair { get; set; }
    [JsonProperty("type")]
    public string Type { get; set; }
    [JsonProperty("price")]
    public string Price { get; set; }
}

OrderCreationResponseDTO показывать нет смысла, только лишних букв добавлю, коих и так не мало. Проблема в том, что сервер возвращает мне ошибку №400 Bad Request, почему он такой прямо Bad - я так и не понял, хотя уже много пытался. Может вы подскажите?

Answer 1

Просто пробовал разные варианты и вот такой - рабочий:

private protected T POST<T>(object jsonDTO, string url, string[] headers = null)
{
    byte[] data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jsonDTO));
    var request = WebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "application/json";
    request.ContentLength = data.Length;
    if (headers != null)
        for (int i = 0; i < headers.Length; i++)
            request.Headers.Add(headers[i]);
    using (Stream requestStream = request.GetRequestStream())
        requestStream.Write(data, 0, data.Length);
    return JsonConvert.DeserializeObject<T>(new StreamReader(((HttpWebResponse)request.GetResponse()).GetResponseStream()).ReadToEnd());
}

Я не стал в деталях изучать в чём разница, во всяком случае пока, но оставлю это здесь, может кому полезно будет.

READ ALSO
Telegram api не подключается

Telegram api не подключается

Для тестирования написал небольшой клиент, идет бесконечное подключение(в streamRead)

182
Размытие Label при перерисовке

Размытие Label при перерисовке

Label привязан к позициям курсора мыши (как подсказка)

147
Чем отличается что лучше использовать?

Чем отличается что лучше использовать?

Скажите пожалуйста чем отличается:

178