Общий метод синтаксического анализа Json

#c# #json #asp.net-core

#c# #json #asp.net-ядро

Вопрос:

У меня есть этот общий метод, который используется для выполнения Post-запроса и последующего анализа ответа следующим образом.

 private async Task<object> PostAsync<T1,T2>(string uri, T2 content)
{
    using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, uri))
    {
        var json = JsonConvert.SerializeObject(content);
        using (var stringContent = new StringContent(json, Encoding.UTF8, "application/json"))
        {
            requestMessage.Content = stringContent;

            HttpResponseMessage response = await _client.SendAsync(requestMessage);
            if (response.IsSuccessStatusCode)
            {
                _logger.LogInformation("Request Succeeded");

                T1 responseModel = JsonConvert.DeserializeObject<T1>(await response.Content.ReadAsStringAsync());
                return  responseModel;
            }
            else
            {
                return await GetFailureResponseModel(response);

            }
        }
    }
}
  

Теперь проблема в том, что некоторые ответы на Post-запрос находятся в SnakeCase, а другие — в camelCase. Как я могу исправить эту проблему.

Ответ №1:

Учитывая, что вы знаете во время компиляции, когда вы знаете snake_case и когда вам нужна стратегия по умолчанию, вы могли бы просто сделать это:

 private Task<object> PostAsync<T1, T2>(string uri, T2 content)
{
    return PostAsync<T1, T2>(uri, content, new DefaultNamingStrategy());
}

private async Task<object> PostAsync<T1, T2>(string uri, T2 content, NamingStragy namingStrategy)
{
    using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, uri))
    {
        var json = JsonConvert.SerializeObject(content);
        using (var stringContent = new StringContent(json, Encoding.UTF8, "application/json"))
        {
            requestMessage.Content = stringContent;

            HttpResponseMessage response = await _client.SendAsync(requestMessage);
            if (response.IsSuccessStatusCode)
            {
                _logger.LogInformation("Request Succeeded");

                var deserializerSettings = new JsonSerializerSettings
                {
                    ContractResolver = new DefaultContractResolver
                    {
                        NamingStrategy = namingStrategy
                    }
                };

                T1 responseModel = JsonConvert.DeserializeObject<T1>(await response.Content.ReadAsStringAsync(), deserializerSettings);
                return responseModel;
            }
            else
            {
                return await GetFailureResponseModel(response);

            }
        }
    }
}
  

Итак, когда вам нужна стратегия по умолчанию:

 await PostAsync<Some1, Some2>(uri, some2Content);
  

и, когда вам нужен snake_case:

 await PostAsync<Some1, Some2>(uri, some2Content, new SnakeCaseNamingStrategy());
  

Комментарии:

1. @camiloTervinto Я уже принял ваш ответ и также реализовал, но не кажется ли вам, что передача стратегии именования в общем методе — это запах кода?

2. @Shabirjan Вовсе нет, это очень распространенный шаблон, и вы можете найти много в исходном коде .NET Framework