JSON Regular Expression and Deserialization Dictionary

1

I'm developing a system that receives JSON from multiple layouts over a single channel, and the Router class must identify which layout is handled by regular expression and perform deserialization for the correct class.

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

Below is 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));

    }
}
    
asked by anonymous 27.09.2018 / 15:45

1 answer

0

Good morning, as I am in the middle of the day, the solution was very 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; }
}

Test the code:

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
    
28.09.2018 / 16:05