Deserialize array of C#objects

Asked

Viewed 134 times

2

Good evening! I have the following script in my View:

$('form').submit(function(e){
        e.preventDefault();

        var resposta = new Array();
        var x = 0;
        var y = 0;
        $(".resposta").each(function () {
                var dados = new Array();
                dados[x] = $(this).children("input[name^='idQuestao']").serialize();
                dados[++x] = $(this).children("input[name^='idQuestionario']").serialize();
                dados[++x] = $(this).children("input[name^='idCampanha']").serialize();
                dados[++x] = $(this).children("input[name^='idFuncionario']").serialize();
                dados[++x] = $(this).find("input[name^='idOpcao']").serialize();

                if(dados[x] === "")
                {
                    dados[x] = $(this).find("select[name^='idOpcao']").serialize();
                }

                if(dados[x] === "")
                {
                    dados[x] = $(this).find("textarea[name^='descricao']").serialize();
                }

                resposta[y] = dados;
                x = 0;
                y++;
        });

        $.ajax({
        type: "POST",
        url: '/Questionario/Create/?questionario=' + JSON.stringify(resposta),
        success: function(result) {
        },
        error: function(result) {
        }
        });
    }); 

In my Controller I am trying to receive as follows:

public ActionResult Create(string questionario)
        {
            try
            {
                var intermediateJson = JsonConvert.DeserializeObject<string>(questionario);
                var oPerson = JsonConvert.DeserializeObject<List<QuestionarioViewModel>>(intermediateJson);

                return View();
            }
            catch(Exception ex)
            {
                return View();
            }
        }

and I’m getting the following error: "Unexpected character encountered while parsing value: [. Path '', line 1, position 1."

This is the string the controller is receiving:

"[[\"idQuestao=1\",\"idQuestionario=1\",\"idCampanha=2\",\"idFuncionario=1\",\"descricao=teste\"],[\"idQuestao=2\",\"idQuestionario=1\",\"idCampanha=2\",\"idFuncionario=1\",\"descricao=teste\"],[\"idQuestao=3\",\"idQuestionario=1\",\"idCampanha=2\",\"idFuncionario=1\",\"idOpcao=2\"],[\"idQuestao=4\",\"idQuestionario=1\",\"idCampanha=2\",\"idFuncionario=1\",\"idOpcao=6\"],[\"idQuestao=5\",\"idQuestionario=1\",\"idCampanha=2\",\"idFuncionario=1\",\"idOpcao=11\"],[\"idQuestao=8\",\"idQuestionario=1\",\"idCampanha=2\",\"idFuncionario=1\",\"descricao=teste\"]]"

I’ve tried several ways, what I’m doing wrong?

  • Try to change the [ & ] for { & }, because in JSON, [ and ] are not valid key characters. You can use X = X.Replace("[", "{").Replace("]", "}") in this case.

  • @T. Borges If any answer has been useful to you, please mark it as accepted , so when other users view your question they will see that you already have a correct answer and accept it for you.

2 answers

3

You are sending an array with array the format of your JSON is getting [ [], [] ] considering this format Jsonconvert expects you to do Deserializeobject for a list, example, List<List<>>.

So if you do as in the example below it will stop giving the error.

var intermediateJson = JsonConvert.DeserializeObject<List<List<string>>>(questionario);

But from what I understood of the purpose of your code you do not need these 2 array, so could send only the data array and convert direct to List<QuestionarioViewModel>


But I believe there are some improvements that can be made to simplify.

Option 1: Send json as date in the post and not by parameter in the url

To make the function safer it would be better to send the parameters in the post date, as in the example below:

<script>
    $('form').submit(function(e){
        e.preventDefault();           

        ....

        $.ajax({
            type: "POST",
            data: { questionario: JSON.stringify(resposta) },
            url: '/Questionario/Create',
            success: function(result) {
            },
            error: function(result) {
            }
        });
    });     
</script>

Option 2: Serialize Form and upload Integer

If your View is typed as List and the inputs are generated by Razor, you can generate them as list and in the end just serialize the form and pass the post, receiving directly into your object. For this you need the Name property of inputs to create a sequence by getting name='[0].idQuestao' for example.

For this to happen your view must create the inputs as in the example below:

@for (var i = 0; i < Model.Count; i++)
{
    <div class='resposta'>
        @Html.HiddenFor(model => model.i].idQuestao)
        @Html.EditorFor(model => model.Itens[i].idOpcao)
    </div>
}

And your script would look like this:

<script>
    $('form').submit(function(e){
        e.preventDefault();           

        $.ajax({
            type: "POST",
            data: $(this).serialize(),
            url: '/Questionario/Create',
            success: function(result) {
            },
            error: function(result) {
            }
        });
    });     
</script>

And the controller so:

[HttpPost]
public ActionResult Create(List<QuestionarioViewModel> respostas)
{

}

2

To facilitate code maintenance, I recommend making two changes, one in the controller and one in the view.

In the view, instead of serializing in array format put into an object, create a model in c# to transit the data as for example:

public class Resposta {
    public int IdQuestao {get;set;}
    public int IdQuestionario {get;set;}
    public int IdCampanha {get;set;}
    public int IdFuncionario {get;set;}
    public int IdOpcao {get;set;}
    public string Descricao {get;set;}
}

In the controller change the method to receive a Reply list

public ActionResult Create(List<Resposta> questionario)
{
    //Nesse momento você já deve possuir toda a lista populada
    try
    {
        return View();
    }
    catch(Exception ex)
    {
        return View();
    }
}

In the view you must make the following change:

$('form').submit(function(e){
    e.preventDefault();

    var resposta = new Array();
    var x = 0;
    var y = 0;
    var dados = [];
    $(".resposta").each(function () {
        var objResposta = {
            IdQuestao: $(this).children("input[name^='idQuestao']").val(),
            IdQuestionario: $(this).children("input[name^='idQuestionario']").val(),
            IdCampanha: $(this).children("input[name^='idCampanha']").val(),
            IdFuncionario: $(this).children("input[name^='idFuncionario']").val(),
            IdOpcao: $(this).find("input[name^='idOpcao']").val(),
            Descricao: $(this).find("textarea[name^='descricao']").val()
        }

        dados.push(objResposta);
    });

    $.ajax({
        type: "POST",
        url: '/Questionario/Create',
        data: JSON.stringify(dados)
        success: function(result) {
        },
        error: function(result) {
        }
    });
});

Browser other questions tagged

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