Как Seriailize объект C # в Json, используя httpClient? - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть небольшая программа, которая должна общаться с "Slack".В более старой версии я использовал "Dictionary<string, string>", а затем поместил их в UrlEncodedContent - все работало нормально.Сейчас я пытаюсь создать Json-объект, используя Nuget-пакет Newtonsoft и (на мой взгляд) форматировать мой объект так, как они говорят на своем веб-сайте.Проблема в том, что когда я пытаюсь сделать простой запрос, моя программа просто запускается до одной конкретной строки в коде (var response = await _httpClient.SendAsync(request);), а затем просто заканчивается.Он не выдает исключение и не отображает никаких сообщений, он просто заканчивается на этой строке.Во время отладки я пошагово прошёл свой код, поэтому я знаю, что он заканчивается именно на этой строке.И я просто не знаю почему!

Теперь мой код: во-первых, мой объект ...

namespace BPS.Slack
{
    public class JsonObject
    {
        //generally needed parameters
        [JsonProperty("ok")]
        public bool ok { get; set; }    
        [JsonProperty("error")]
        public string error { get; set; }   
        [JsonProperty("channel")]
        public string channel { get; set; }
        [JsonProperty("token")]
        private string token = "xoxp-MyToken";
        [JsonProperty("as_user")]
        public bool as_user = false;       
        [JsonProperty("username")]
        public string username { get;set; } 
        //--------------------------------
        //only needed for textmessages
        [JsonProperty("text")]
        public string text { get; set; }
        //--------------------------------
        //for posting messages with data attached
        [JsonProperty("initial_comment")]
        public string initial_comment { get; set; }
        [JsonProperty("file")]
        public string file { get; set; }
        [JsonProperty("channels")]
        public string channels { get; set; }
        //--------------------------------
        //for getting the latest message from a channel
        [JsonProperty("count")]
        public string count = "1";
        [JsonProperty("unreads")]
        public bool unreads = true;
    }
}

теперь клиент:

   namespace BPS.Slack
    {
        public class BpsHttpClient
        {
            private readonly HttpClient _httpClient = new HttpClient { };
            public Uri UriMethod { get; set; }

            public BpsHttpClient(string webhookUrl)
            {
                UriMethod = new Uri(webhookUrl);
            }


            public async Task<HttpResponseMessage> UploadFileAsync(MultipartFormDataContent requestContent)
            {
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, UriMethod);
                request.Content = requestContent;
                var response = await _httpClient.SendAsync(request);

                return response;
            }
        }

    }

и основной

namespace TestArea
{
    class MainArea
    {
        public static void Main( string[] args)
        {
            try
            {
                Task.WhenAll(SendMessage());
            }
            catch(Exception ass)
            {
                Console.WriteLine(ass);
                Console.ReadKey();
            }
        }
        private static async Task SendMessage()
        {
            var client = new BpsHttpClient("https://slack.com/api/im.history");
            JsonObject JO = new JsonObject();
            JO.channel = "DCW21NBHD";            
            var Json = JsonConvert.SerializeObject(JO);

            var StringJson = new StringContent(Json, Encoding.UTF8);
            MultipartFormDataContent content = new MultipartFormDataContent();
            content.Add(StringJson);

            var Response = await client.UploadFileAsync(content);


            string AnswerContent = await Response.Content.ReadAsStringAsync();

            Console.WriteLine(AnswerContent);
            Console.ReadKey();
        }
    }

}

У меня была та же проблема в моей старой версии, НО только потому, что я хотел DEserialize ответ, который я получил от Slack.Это было связано с моим объектом, на который я пытался сделать десериализацию ответа.Но на этот раз я не могу понять, что не так.Но, как я уже сказал, у меня нет опыта использования сериализованных объектов в качестве Json-свойства для отправки запросов ... у кого-нибудь есть идеи, что не так с моим кодом?

РЕДАКТИРОВАТЬ: Эта проблема вроде как решена.Но есть последующая проблема.

Хорошо, я обнаружил, что причиной прекращения работы abprubt была

Task.WhenAll (SendMessage ());

должно быть

Task.WaitAll (SendMessage ());Зачем???Кто-то сказал, что я должен использовать WhenAll, но очевидно, что в этом случае он не работает должным образом ...

Теперь я получаю ответ от Slack, но теперь возникла другая проблема.Когда я использую этот метод:

    public async Task<HttpResponseMessage> UploadFileAsync(MultipartFormDataContent requestContent)
    {
        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, UriMethod);
        request.Content = requestContent;
        var response = await _httpClient.SendAsync(request);

        return response;
    }

Я всегда получаю ответ:

{"ok": false, "error": "invalid_form_data"}

, поэтому я попытался явно указать ему «mediaType», я попытался «application / json» и другие, но со всеми из них я получаю ту же ошибку.Вот полный метод, который вызывает верхний метод:

 private static async Task SendMessage()
    {
        var client = new BpsHttpClient("https://slack.com/api/chat.postMessage");
        JsonObject JO = new JsonObject();
        JO.channel = "DCW21NBHD";
        JO.text = "This is so much fun :D !";
        var Json = JsonConvert.SerializeObject(JO, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });

        var StringJson = new StringContent(Json, Encoding.UTF8, "application/json");

        var requestContent = new MultipartFormDataContent();
        requestContent.Add(StringJson);

        var Response = await client.UploadFileAsync(requestContent);

        string AnswerContent = await Response.Content.ReadAsStringAsync();

    }

Когда я использую этот метод:

    public async Task<HttpResponseMessage> SendMessageAsync(FormUrlEncodedContent content)
    {
        var response = await _httpClient.PostAsync(UriMethod, content);

        return response;
    }

, поэтому в основном я передаю "FormUrlEncodedContent" вместо "MultipartFormDataContent" в этоми тогда я получаю ответ, который хочу, и могу работать с ним.НО это мне мало пригодится, так как я должен использовать «MultipartFormDataContent», чтобы иметь возможность отправлять файлы с моими запросами.

У кого-нибудь есть идеи, что здесь не так?Почему ему не нравится один тип контента, а другой?Буду благодарен за советы и идеи!

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

поэтому я понял, что в Main () проблема была в следующем:

Task.WhenAll(SendMessage());

Вместо этого я должен использовать:

 Task.WaitAll(SendMessage());

Любой, кто имеет больше знаний по этому вопросу, пожалуйста,уточни почему!

0 голосов
/ 03 декабря 2018

Вы сериализуете свой объект в Json, а затем добавляете его в составное тело, это довольно странно.Если вы не загружаете двоичные данные (например, файлы), нет необходимости использовать MultipartFormDataContent.

Вы можете напрямую опубликовать свой JsonObject, сериализованный как JSON:

        public async Task<HttpResponseMessage> PostJsonAsync(StringContent content)
        {                
            var response = await client.PostAsync(url, content);

            return response;
        }

       var client = new BpsHttpClient("https://slack.com/api/im.history");                  
       JsonObject JO = new JsonObject();
       JO.channel = "DCW21NBHD";            
       var Json = JsonConvert.SerializeObject(JO);
       var StringJson = new StringContent(Json, Encoding.UTF8);
       var Response = await client.PostJsonAsync(content);

Также это должно быть POST для функции UploadFileAsync.

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, UriMethod);
...