0
respostas

[Projeto] Desserializando Filmes - Conversor automático

Gostaria de observar aqui que no JSON dos Filmes as informações do ANO e a NOTA DO IMDB estão entre aspas, o que acaba vindo para o C# como sendo STRING ao invés de INT e DECIMAL(ou DOUBLE) respectivamente, portanto foi preciso converter essas informações para o seu respectivo tipo correto.

Primeiro eu pensei em ter uma variável a mais para fazer o int.Parse e o double.Parse, mas vi que seria algo muito manual e que teria que fazer isso para vários campos caso o JSON, por exemplo, tivesse diversos campos na mesma condição. Então pesquisei uma forma de fazer essa conversão antes de atribuir o valor do campo do JSON na minha variável dentro da classe, e foi aí que descobri (com a ajuda do Gemini) a possibilidade de criar um conversor genérico automático.

Achei muito legal esse conversor, apesar de não entender 100% dele ainda porque ainda não exploramos muitos recursos de JSON no curso ainda. Enfim, mesmo assim fiz e segue abaixo como ficou o exercício.

Classe Filme:

using System.Reflection.Metadata.Ecma335;
using System.Text.Json.Serialization;
namespace Filmes.Modelos;
internal class Filme
{
    [JsonPropertyName("title")]
    public string Nome { get; set; }

    [JsonPropertyName("year")]
    [JsonConverter(typeof(StringToNumberConverter<int>))]
    public int? Ano { get; set; }

    [JsonPropertyName("imDbRating")]
    [JsonConverter(typeof(StringToNumberConverter<decimal>))]
    public decimal? Nota { get; set; }

    public void ExibirDetalhesDoFilme()
    {
        Console.WriteLine($"Nome do filme: {Nome}");
        Console.WriteLine($"Ano de lançamento: {Ano}");
        Console.WriteLine($"Nota IMDB: {Nota}");
    }
}

Classe StringToNumberConverter (Conversor):

using System.Globalization;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Filmes.Modelos;
internal class StringToNumberConverter<T> : JsonConverter<T> where T : IConvertible
{
    public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String)
        {
            var stringValue = reader.GetString();
            if (string.IsNullOrEmpty(stringValue))
            {
                return default;
            }
            // Converte a string para o tipo T
            return (T)Convert.ChangeType(stringValue, typeof(T), CultureInfo.InvariantCulture);
        }
        else if (reader.TokenType == JsonTokenType.Number)
        {
            // Se já for um número, usa a conversão padrão
            return JsonSerializer.Deserialize<T>(ref reader, options);
        }

        throw new JsonException($"Não foi possível converter o valor para o tipo {typeof(T).Name}");
    }

    public override void Write (Utf8JsonWriter writer, T value, JsonSerializerOptions options)
    {
        // Implementaçãopara escrita (serialização), se necessário
    }
}

Program Filmes:

using Filmes.Modelos;
using System.Text.Json;

using (HttpClient client = new HttpClient())
{
    try
    {
        string resposta = await client.GetStringAsync("https://raw.githubusercontent.com/ArthurOcFernandes/Exerc-cios-C-/curso-4-aula-2/Jsons/TopMovies.json");
        //Console.WriteLine(resposta);
        var filmes = JsonSerializer.Deserialize<List<Filme>>(resposta);
        Console.WriteLine($"Existem {filmes.Count} filmes na lista.\n");
        Console.WriteLine("Pressione ENTER para exibir os detalhes dos filmes...");
        Console.ReadKey();
        Console.WriteLine();
        filmes[1].ExibirDetalhesDoFilme();
    } 
    catch (Exception ex)
    {
        Console.WriteLine($"Erro: {ex}");
    }
}