Convert value to C#object

Asked

Viewed 979 times

-1

I am doing an integration where the system uses socket connection, I send and receive messages to reach an end, and the messages comes in this format:

aplicacao="Teste"
retorno="1"
sequencial="191"
servico="iniciar"
versao="1.0.0"

My question is, is there any way to turn these messages into objects?

Edit1:

Call method:

private bool transacaoTEF(string formaPagamento, string valor, string parcelas, string tipoTransacao)
    {
        string coleta = string.Empty;
        string resposta = string.Empty;
        int s = TEF.Metodos.Sequencial();
        int sa = 1;
        valor = valor.Replace(",", ".");

        if (!TEF.Metodos.Conectar()) return false;

        Iniciar:

        // INICIAR
        resposta = TEF.Metodos.IniciaTransacao(s.ToString());

        if (resposta.Contains("retorno=\"2\""))
        {
            s += 2;
            goto Iniciar;
        }

        if (resposta.Contains("retorno=\"1\""))
        {
            s += 1;
            resposta = TEF.Metodos.TipoTransacao(valor, s.ToString(), tipoTransacao);
        }

        while (true)
        {
            if (resposta.Contains("retorno=\"0\""))
            {
                if (resposta.Contains("automacao_coleta_tipo"))
                {
                    using (ColetaTefForm form = new ColetaTefForm(resposta))
                        if (form.ShowDialog() == DialogResult.OK)
                            coleta = form.coleta;

                    sa = Convert.ToInt32(TEF.Metodos.RetornaValor(resposta, "automacao_coleta_sequencial"));
                    resposta = TEF.Metodos.AutomacaoColetaInformacao(sa.ToString(), coleta);
                    continue;
                }
                if (resposta.Contains("automacao_coleta_mensagem"))
                {
                    MessageBox.Show(TEF.Metodos.RetornaValor(resposta, "automacao_coleta_mensagem"));
                    sa = Convert.ToInt32(TEF.Metodos.RetornaValor(resposta, "automacao_coleta_sequencial"));
                    resposta = TEF.Metodos.Processar(sa.ToString());
                    continue;
                }
                if (resposta.Contains("transacao_comprovante"))
                {
                    s = Convert.ToInt32(TEF.Metodos.RetornaValor(resposta, "automacao_coleta_sequencial"));
                    TEF.Metodos.ConfirmarTransacao(s.ToString(), tipoTransacao);
                    TEF.Metodos.Finalizar((s + 1).ToString());
                    return true;
                }
            }
            if (resposta.Contains("retorno=\"9\""))
            {
                MessageBox.Show(TEF.Metodos.RetornaValor(resposta, "mensagem"));
            }
        }

        return false;
    }

Class "Methods"

public class Metodos
{
    private static TcpClient tcpClient;
    private static NetworkStream networkStream;

    public static bool Conectar()
    {
        try
        {
            string host = ConfigurationManager.AppSettings["host"];
            string port = ConfigurationManager.AppSettings["port"];
            tcpClient = new TcpClient();
            tcpClient.Connect(host, Convert.ToInt32(port));
            return true;
        }
        catch (Exception e)
        {
            MensagemErro(e);
            return false;
        }
    }

    public static int Sequencial()
    {
        try
        {
            if (File.Exists(AppDomain.CurrentDomain.BaseDirectory + "/sequencial.txt"))
                return Convert.ToInt32(File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "/sequencial.txt"));
            else
            {
                File.Create(AppDomain.CurrentDomain.BaseDirectory + "/sequencial.txt").Dispose();
                return 1;
            }
        }
        catch (Exception e)
        {
            MensagemErro(e);
            return 0;
        }
    }

    public static void SalvarSequencial(string s)
    {
        try
        {
            File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "/sequencial.txt", s);
        }
        catch (Exception e)
        {
            MensagemErro(e);
        }
    }

    public static string IniciaTransacao(string sequencial)
    {
        return Retorno("aplicacao=\"ProComercio\" " +
                       "versao=\"1.0.0\" " +
                       "retorno=\"1\" " +
                       "sequencial=\"" + sequencial + "\" " +
                       "servico=\"iniciar\"");
    }

    public static string TipoTransacao(string valor, string sequencial, string tipoTransacao)
    {
        if (valor.Contains(","))
            valor = valor.Replace(",", ".");

        return Retorno("retorno=\"1\" " +
                       "sequencial=\"" + sequencial + "\" " +
                       "servico=\"executar\" " +
                       "transacao=\"" + tipoTransacao + "\" " +
                       "transacao_valor=\"" + valor + "\"");
    }

    public static string AutomacaoColetaInformacao(string sequencial, string informacao)
    {
        return Retorno("automacao_coleta_sequencial =\"" + sequencial + "\" " +
                       "automacao_coleta_retorno=\"0\" " +
                       "automacao_coleta_informacao=\"" + informacao + "\"");
    }

    public static string Processar(string sequencial)
    {
        return Retorno("automacao_coleta_sequencial =\"" + sequencial + "\" " +
                       "automacao_coleta_retorno=\"0\"");
    }

    public static string ConfirmarTransacao(string sequencial, string tipoTransacao)
    {
        return Retorno("sequencial =\"" + sequencial + "\" " +
                       "retorno=\"0\" " +
                       "servico=\"executar\" " +
                       "transacao=\"" + tipoTransacao + "\"");
    }

    public static string Finalizar(string sequencial)
    {
        return Retorno("retorno=\"1\" " +
                       "sequencial =\"" + sequencial + "\" " +
                       "servico=\"finalizar\"");
    }

    public static string RetornaValor(string resposta, string palavraChave)
    {
        string[] lista = resposta.Split(new[] { "\n" }, StringSplitOptions.None);
        string linha = "";
        foreach (string l in lista)
        {
            if (l.Contains(palavraChave + "=\""))
            {
                linha = l;
            }
        }
        return linha.Split(new[] { "\"" }, StringSplitOptions.None)[1];
    }

    public static string ViaEstabelecimento(string nota)
    {
        int inicio = nota.LastIndexOf("transacao_comprovante_1via=\"");
        int final = nota.IndexOf("transacao_comprovante_2via=\"");

        string comprovante = nota.Substring(inicio, final - inicio);
        return comprovante.Split(new[] { "\"" }, StringSplitOptions.None)[1];
    }

    public static string ViaCliente(string nota)
    {
        int inicio = nota.LastIndexOf("transacao_comprovante_2via=\"");
        int final = nota.IndexOf("transacao_data");

        string comprovante = nota.Substring(inicio, final - inicio);
        return comprovante.Split(new[] { "\"" }, StringSplitOptions.None)[1];
    }

    public static string Retorno(string msg)
    {
        try
        {
            if (!string.IsNullOrEmpty(msg))
            {
                networkStream = tcpClient.GetStream();
                byte[] sendBytes = Encoding.ASCII.GetBytes(msg);
                networkStream.Write(sendBytes, 0, sendBytes.Length);
            }
            byte[] bytes = new byte[tcpClient.ReceiveBufferSize];
            networkStream.Read(bytes, 0, Convert.ToInt32(tcpClient.ReceiveBufferSize));
            string retorno = Encoding.ASCII.GetString(bytes);
            return retorno;
        }
        catch (Exception e)
        {
            MensagemErro(e);
            return null;
        }
    }

    public static void MensagemErro(Exception e)
    {
        MessageBox.Show("Ocorreu um erro com o V$PagueClient!\n\n" + e, "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

I’m using substring at the moment, but it’s not accurate, because some answers come like this: https://textuploader.com/153ev

  • 2

    Yes, it is possible, present your code

  • I just need a practical example with any string, the code is too long to run here

  • Always comes in the same format the return?

  • Yes @Gustavoluciano

  • @Leandroangelo posted the code

  • Why not instantiate the class and pass the attributes ?

  • I don’t quite understand @Joypeter, how can I do that? This data I get comes as string

  • Creates a class with the return attributes and then instants passing the values to the respective attribute.

  • In this part I’m having difficulties @Joypeter, how can I do it?

Show 4 more comments

2 answers

1

As your question appealed a variable input format it is difficult to stipulate a standardized class format to accommodate your data.

What I did was create an parser so that it accepts any input string and returns a dictionary whose keys and values are both strings. This analyzer searches for the standard attribute name="value" and fills the dictionary with the key being the attribute name and key value being "value" without the quotation marks.

As a test resource I created a file called "Entrada.txt" whose content is the return you passed on the link https://textuploader.com/153ev.

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;

public class Analisador
{
   public static Dictionary<string,string> Parse(string entrada)
   {
      //cria o dicionário que será devolvido pela função
      Dictionary<string,string> resultado =new Dictionary<string,string>();

      // Analiza a string de entrada em busca do padrão nome_atributo="valor"
      MatchCollection matches = Regex.Matches(entrada, "[^\\s\\\"]+=\\\"[^\\\"]+\\\"");

      //Varre o conjunto de resultados e os armazena no dicionário      
      foreach (Match match in matches)
      {
        // separa o atributo de seu valor
        string[] arr = match.Value.Split('='); 

        //Insere a chave sem espaços laterais e o valor sem aspas no dicionário
        resultado.Add(arr[0], arr[1].Replace("\"", ""));
      }

      // retorna o dicionário
      return resultado;
   }

   public static void Main()
   {
      Dictionary<string,string> Valores = Parse(File.ReadAllText(@"Entrada.txt"));      

      foreach(var item in Valores)
      {
        Console.WriteLine($"{item.Key} = {item.Value}");
      }
   }
}

From this code you can create a class that meets your needs and fill in the fields with the values of the dictionary.

  • The code in Repl.it I will not add the answer as it is public handling someone can delete or modify. It is then as a comment. PS: the Repl.it display window is kind of mocked 'Consecutive Writelines' do not start in the first column.

0


First creates the class with the return property

public class PropriedaRetorno
{
    public string Aplicacao { get; set; }
    public string Retorno { get; set; }
    public string Sequencial { get; set; }
    public string Servico { get; set; }
    public string Versao { get; set; }
}`

Here we do the conversion, it takes a string parameter which is the return in string and returns the object. According to the structure of the string that you presented this logic is functional:

   public static PropriedaRetorno Convert(string retorno)
    {
        PropriedaRetorno pr = new PropriedaRetorno();
        pr.Aplicacao = GetValeu(retorno, "aplicacao"); 
        pr.Retorno = GetValeu(retorno, "retorno");
        pr.Sequencial = GetValeu(retorno, "sequencial");
        pr.Servico = GetValeu(retorno, "servico");
        pr.Versao = GetValeu(retorno, "versao");
        return pr;
    }

The function receives the return and the key and returns the value corresponding to the key.

    public string GetValeu(string retorno, string key)
    {
        string valeu = "";
        int i = retorno.LastIndexOf(key + "=\"");
        i += key.Length + 2;
        while (i <= retorno.Length)
        {
            char ch=retorno[i];
            if ( ch== '\"')
                break;
            valeu += ch;
            i++;
        }
        return valeu;
    }

That way you have more freedom, you can add more attribute in the class and then add also in the Convert attribute function.

ex: pr.Sequencial = GetValeu(retorno, "sequencial");

  • Does this form apply to this type of return as well? https://textuploader.com/153ev

  • No. I just followed the feedback you presented in the question.

  • I edited a little bit after you presented the solution, would have a way to convert the string of that link?

  • There is. but I will need to know the beginning and end of the filter you need, and the pattern of these strings.

  • The default would be: name_do_attribute="value" name_do_attribute="value2"

  • Separated from each other by space

  • Okay, I get it, I’m gonna edit the answer.

  • It is already edited

Show 3 more comments

Browser other questions tagged

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