Во время Rest запроса появляются символы?
Написал запрос на сайт
public static string UTCtime()
{
string url = "http://worldtimeapi.org/api/timezone/Europe/Berlin";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
string response ;
StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
response = streamReader.ReadToEnd();
streamReader.Close();
IRoot myDeserializedClass = JsonConvert.DeserializeObject<IRoot>(response);
string[] UTC = myDeserializedClass.utc_datetime.Split('.');
string UTCg = UTC[0].Replace(":","%3A");
Console.WriteLine(UTCg);
return UTCg;
}
Результат этого запроса используется в другом запросе и вот тут начинаются проблемы.Дело в том что вот значение, которое должно отправляться в последующем запросе
2021-09-07T19%3A07%3A10
А вот значение ,которое отправляется по факту
2021-09-07T19%3**25**A07%3**25**A10
В чем проблема не очень понятно. Для большей ясности вот дата которую обрабатываю
2021-09-07T17:29:18
мой код запроса, где используется метод
var request = new RestRequest("/v1/account/accounts");
request.AddQueryParameter("AccessKeyId", apikey);
request.AddQueryParameter("SignatureMethod", "HmacSHA256");
request.AddQueryParameter("SignatureVersion", "2");
request.AddQueryParameter("Timestamp", UTCtime());
request.AddQueryParameter("Signature", CreateSignature(request.Parameters, secret,Method,endpoint,base_uri));
var response = client.Get(request); string Response = response.Content;
Ответы (1 шт):
Если задача в получении времени из сети именно из этой API, то вы слишком хардкорно подошли к вопросу, все делается намного проще.
Беру строковый ответ API, копирую в буфер обмена Crtl+C.
{
"abbreviation": "CEST",
"client_ip": "x.x.x.x",
"datetime": "2021-09-08T09:03:41.483887+02:00",
"day_of_week": 3,
"day_of_year": 251,
"dst": true,
"dst_from": "2021-03-28T01:00:00+00:00",
"dst_offset": 3600,
"dst_until": "2021-10-31T01:00:00+00:00",
"raw_offset": 3600,
"timezone": "Europe/Berlin",
"unixtime": 1631084621,
"utc_datetime": "2021-09-08T07:03:41.483887+00:00",
"utc_offset": "+02:00",
"week_number": 36
}
Открываю студию, выбираю меню Edit - Paste Special - Paste JSON as classes, получаю класс, переименовываю его, получается код:
public class WorldTimeResponse
{
public string abbreviation { get; set; }
public string client_ip { get; set; }
public DateTime datetime { get; set; }
public int day_of_week { get; set; }
public int day_of_year { get; set; }
public bool dst { get; set; }
public DateTime dst_from { get; set; }
public int dst_offset { get; set; }
public DateTime dst_until { get; set; }
public int raw_offset { get; set; }
public string timezone { get; set; }
public int unixtime { get; set; }
public DateTime utc_datetime { get; set; }
public string utc_offset { get; set; }
public int week_number { get; set; }
}
Лишнее можно конечно выкинуть отсюда.
Далее, вы используете HttpWebRequest, который устарел, когда я еще был маленький и ничего не знал про C#. Закопайте его обратно. Нужно использовать HttpClient.
private static readonly HttpClient client = new HttpClient();
public static async Task<DateTime> UTCtime()
{
string url = "http://worldtimeapi.org/api/timezone/Europe/Berlin";
WorldTimeResponse time = await client.GetFromJsonAsync<WorldTimeResponse>(url);
return time.utc_datetime.ToUniversalTime();
}
И вот вы уже из метода получаете не непонятную строчку, а готовый экземпляр DateTime.
Далее можно с ним делать что угодно, например вот это:
DateTime time = await UTCtime();
Console.WriteLine(time.ToString("s"));
Console.WriteLine(time.ToString("yyyy-MM-ddTHH:mm"));
Console.WriteLine(HttpUtility.UrlEncode(time.ToString("s")).ToUpper());
Console.WriteLine(HttpUtility.UrlEncode(time.ToString("yyyy-MM-ddTHH:mm")).ToUpper());
Вывод в консоль
2021-09-08T07:46:37
2021-09-08T07:46
2021-09-08T07%3A46%3A37
2021-09-08T07%3A46
Кстати, выбранная вами API медленная, экземпляр DateTime можно получить гораздо быстрее. Например с использованием протокола Network Time Protocol (NTP).
public static async Task<DateTime> GetNetworkTimeAsync(string ntpServer, int timeout = 500)
{
byte[] ntpData = new byte[48];
ntpData[0] = 0x1B;
double jitter = 0;
using (UdpClient client = new UdpClient(ntpServer, 123))
{
Task<UdpReceiveResult> receiveTask = client.ReceiveAsync(); // начинаем ждать ответа
DateTime now = DateTime.Now;
await client.SendAsync(ntpData, ntpData.Length); // и только потом отправляем запрос
if (receiveTask == await Task.WhenAny(receiveTask, Task.Delay(timeout)))
ntpData = receiveTask.Result.Buffer;
else
throw new TimeoutException("Timeout occured while waiting for NTP server response");
jitter = (DateTime.Now - now).TotalMilliseconds / 2; // разброс = пинг / 2, для меня это примерно 25 мс
}
byte[] data = ntpData[40..];
Array.Reverse(data);
uint fraction = BitConverter.ToUInt32(data);
uint seconds = BitConverter.ToUInt32(data, 4);
double milliseconds = (double)seconds * 1000 + (double)fraction * 1000 / 0x100000000L + jitter;
DateTime networkDateTime = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(milliseconds);
return networkDateTime;
}
Использовать просто
DateTime time = await GetNetworkTimeAsync("pool.ntp.org");
Результат тот же, но работает почти мгновенно, а не полторы секунды, как API.
Но зачем вообще отправлять запрос за временем в сеть? Ведь можно просто сделать вот так:
DateTime time = DateTime.UtcNow;
По поводу отправляемого запроса, вам не нужно кодировать в Url Encoding, RestClient должен делать это автоматически. Просто вот так:
request.AddQueryParameter("Timestamp", DateTime.UtcNow.ToString("s"));
Кстати, вместо RestClient я бы тоже предложил использовать HttpClient. Примеров его использования в сети очень много.