JSON Regular Expression and Deserialization Dictionary

Asked

Viewed 239 times

1

I am developing a system that receives JSON from several layouts for a single channel and the Router class must identify which layout is by regular expression and perform the deserialization for the correct class.

In the prototype I used if nested, but would like a more dynamic solution, thought to use dictionary with key being the Regex and the value the class to be deserialized, but would like help if this would be the best solution (and how best to implement) or if another solution would be indicated.

Below the code I started to develop:

public class Roteador {

    internal static RegexOptions regOpcoes = RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled;

    internal static string PatternMsg0002 = "\"Event\"(\\s)*:(\\s)*\"Msg0002\"?";
    internal static string PatternMsg0003 = "\"Event\"(\\s)*:(\\s)*\"Msg0003\"?";
    internal static string PatternMsg0003 = "\"Event\"(\\s)*:(\\s)*\"Msg0004\"?";

    internal static Regex regexMsg0002 = new Regex(PatternMsg0002, regOpcoes);
    internal static Regex regexMsg0003 = new Regex(PatternMsg0003, regOpcoes);
    internal static Regex regexMsg0004 = new Regex(PatternMsg0004, regOpcoes);

    internal static Dictionary<Regex, ClasseBase> dicRegex = new Dictionary<Regex, ClasseBase>();

    public static void IntegrarMensagem(string mensagem)
    {

        JsonSerializer serializer = new JsonSerializer();
        ClasseBase meuObjeto;

        if (regexMsg0002.IsMatch(mensagem))
            meuObjeto = (ClasseFilha1)serializer.Deserialize(textoJson, typeof(ClasseFilha1));
        else if (regexMsg0003.IsMatch(mensagem))
            meuObjeto = (ClasseFilha2)serializer.Deserialize(textoJson, typeof(ClasseFilha2));
        else if (regexMsg0004.IsMatch(mensagem))
            meuObjeto = (ClasseFilha3)serializer.Deserialize(textoJson, typeof(ClasseFilha3));

    }
}

1 answer

0

Good morning, as I’m in the middle of the day the solution was quite messy but I hope you understand:

Router:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using Testes.Models;

public class Roteador
{
    private readonly Dictionary<string, Regex> DicionarioDePadroes;
    private readonly Dictionary<string, Func<string, ClasseBase>> DicionarioDeDesserializadores;

    public Roteador(string rotas)
    {
        var dicionarioTemporario = JsonConvert.DeserializeObject<Dictionary<string, string>>(rotas);
        DicionarioDePadroes = new Dictionary<string, Regex>(dicionarioTemporario.Count);
        dicionarioTemporario.ToList().ForEach(kvp =>
        {
            try
            {
                DicionarioDePadroes.Add(kvp.Key, new Regex(kvp.Value, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled));
            }
            catch
            {

            }
        });
        DicionarioDeDesserializadores = new Dictionary<string, Func<string, ClasseBase>>();
        foreach (var kvp in DicionarioDePadroes)
        {
            var type = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(t => t.Name == kvp.Key);
            if (type != default(Type) && type.IsSubclassOf(typeof(ClasseBase)))
                DicionarioDeDesserializadores.Add(kvp.Key, jsonValue => (ClasseBase)JsonConvert.DeserializeObject(jsonValue, type));
        }
    }

    public ClasseBase IntegrarMensagem(string mensagem)
    {
        ClasseBase meuObjeto = null;

        var nomeClasse = DicionarioDePadroes.Where(kvp => kvp.Value.IsMatch(mensagem))?.Select(kvp => kvp.Key).FirstOrDefault();
        if (!string.IsNullOrEmpty(nomeClasse) && DicionarioDeDesserializadores.TryGetValue(nomeClasse, out Func<string, ClasseBase> parser))
            meuObjeto = parser(mensagem);

        return meuObjeto;
    }
}

Base Class

using Newtonsoft.Json;
public class ClasseBase
{
    [JsonProperty]
    private string Event { get; set; }
}

Class 1:

using System;
public class Classe1 : ClasseBase
{
    public int Param1 { get; set; }
    public DateTime Param2 { get; set; }
}

Class 2:

public class Classe2 : ClasseBase
{
    public int Param1 { get; set; }
    public string Param2 { get; set; }
}

Code test:

var formatos = "{\"Classe1\": \"\\\"Event\\\"(\\\\s)*:(\\\\s)*\\\"Classe1\\\"?\\\"\", \"Classe2\": \"\\\"Event\\\"(\\\\s)*:(\\\\s)*\\\"Classe2\\\"?\\\"\"}";
var roteador = new Roteador(formatos);
#region Testes de desserialização da Classe1 e Classe2
var jsonValueClasse1 = "{\"Event\":\"Classe1\",\"Param1\":5,\"Param2\":\"2018-05-22T22:00:00.000\"}";
var jsonValueClasse2 = "{\"Event\":\"Classe2\",\"Param1\":5,\"Param2\":\"Testes\"}";

var classe1 = roteador.IntegrarMensagem(jsonValueClasse1);
var classe2 = roteador.IntegrarMensagem(jsonValueClasse2);

#endregion

Browser other questions tagged

You are not signed in. Login or sign up in order to post.