none
$.ajax() não acessa Action Method RRS feed

  • Pergunta

  • Salve!

    Eu tenho a seguinte View. Essa View apresenta numa tabela uma lista de itens. A coluna mais à esquerda de cada linha tem um checkbox para permitir ao usuário que marque o item para importação.

    @model Estrutural.UI.ViewModels.ImportarViewModel
    
    @{
        ViewBag.Title = "Importação de Itens";
    }
    
    @section Scripts {
        <script type="text/javascript">
            $(document).ready(function () {
    
                $('#btnImportar').click(function (e) {
                    var lstIntItens = [];
                    // Checa os itens marcados e os inclui em lstIntItens
                    $('.table > tbody > tr').each(function () {
                        if ($(this).find('input:checkbox').is(':checked')) {
                            lstIntItens.push($(this).find('input:checkbox').data('id'));
                        }
                    });
                    var modelo = {
                        ItensAImportar: lstIntItens,
                        OrcamentoId: $('#OrcamentoId').val(),
                        Exercicio: $('#Exercicio').val(),
                        InformadoPor: $('#InformadoPor').val()
                    };
                    $.ajax({
                        type: 'POST',
                        url: '/Orcamento/Importar',
                        dataType: 'json',
                        data: JSON.stringify(modelo),
                        contentType: 'application/json;charset=utf-8',
                        success: function () {
                            window.location.href = "/Itens/Index/?ano=" + $('#Exercicio').val();
                        },
                        error: function (jqXHR, error, errorThrown) {
                            mostraMensagem("Importação de itens", "erro", "Ocorreu um problema ao tentar importar os itens ('" + errorThrown + "')!");
                        }
                    });
                });
            })
        </script>
    }
    
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
        <div class="panel panel-primary">
            <div class="panel-heading"><h4>Itens do exercício anterior</h4></div>
            <div class="panel-body">
                <div class="form-horizontal">
                    @Html.HiddenFor(model => model.Exercicio)
                    @Html.HiddenFor(model => model.OrcamentoId)
                    @Html.HiddenFor(model => model.InformadoPor)
                    <table class="table table-bordered">
                        <thead>
                            <tr>
                                <th></th>
                                <th class="text-center">Tipo de Gasto</th>
                                <th class="text-center">Descrição</th>
                                <th class="text-center">Valor</th>
                            </tr>
                        </thead>
                        <tbody>
                            @foreach (var item in Model.LstItens)
                            {
                                <tr>
                                    <td><input type="checkbox" data-id="@item.Id" title="Clique para marcar o item para importação" /></td>
                                    <td>
                                        @Html.DisplayFor(modelItem => item.TipoDeGasto.Descricao)
                                    </td>
                                    <td>
                                        @Html.DisplayFor(modelItem => item.Descricao)
                                    </td>
                                    <td class="text-right">
                                        @Html.DisplayFor(modelItem => item.ValorOriginal)
                                    </td>
                                </tr>
                            }
                        </tbody>
                    </table>
                </div>
            </div>
            <div class="panel-footer">
                <p class="text-right">
                    @Html.ActionLink("Cancelar", "Detalhe", "Orcamento", new { id = Model.OrcamentoId }, new { @class = "btn btn-default" })
                    <input type="button" id="btnImportar" value="Importar itens marcados" class="btn btn-primary" />
                </p>
            </div>
        </div>
    }

    O Model é assim:

    usings ..... 
    namespace Estrutural.UI.ViewModels
    {
        public class ImportarViewModel
        {
            private DbEstrutural db = new DbEstrutural();
    
            public List<Item> LstItens { get; set; }
            public int Exercicio { get; set; }
            public int OrcamentoId { get; set; }
            public List<int> ItensAImportar { get; set; }
            public string InformadoPor { get; set; }
    
            public ImportarViewModel(int ano, Usuario ouser)
            {
                this.LstItens = db.Itens.Where(i => i.Exercicio == ano - 1 && i.Rateio.Count == 0).ToList();
                this.InformadoPor = ouser.Nome;
                this.OrcamentoId = db.Orcamento.Where(i => i.Exercicio == ano).First().OrcamentoId;
                this.Exercicio = ano;
                this.ItensAImportar = new List<int>();
            }
        }
    }

    E o Action Method é:

    public ActionResult Importar(ImportarViewModel modelo)
    {
        foreach (var item in modelo.ItensAImportar)
        {
            Item itemOrcOriginal = db.Itens.Find(item);
            Item itemNovoOrc = new Item();
            itemNovoOrc.OrcamentoId = modelo.OrcamentoId;
            itemNovoOrc.Exercicio = modelo.Exercicio;
            itemNovoOrc.Descricao = itemOrcOriginal.Descricao;
    
            ... 
        }
        return View();
    }

    O problema é que a chamada do $.ajax no código javascript da View nunca chega a esse método.

    Eu não estou conseguindo o erro no código. Espero a ajuda dos especialistas desse forum.

    Grato pela atenção de todos.

    Paulo Ricardo Ferreira

    sexta-feira, 24 de junho de 2016 17:02

Respostas

  • Salve!

    Resolvi o problema alterando a classe que serve como model, ImportarViewModel. Retirei dela o construtor. Daí atribuí os seus valores no controller.

    Ficou assim:

    using ...
    namespace Estrutural.UI.ViewModels
    {
        public class ImportarViewModel
        {
            private DbEstrutural db = new DbEstrutural();
    
            public List<Item> LstItens { get; set; }
            public int Exercicio { get; set; }
            public int OrcamentoId { get; set; }
            public string InformadoPor { get; set; }
            public List<int> ItensAImportar { get; set; }
        }
    }

    Dessa forma o método é chamado com todas as informações que necessito.

    Grato pela atenção de todos.

    Paulo Ricardo Ferreira

    sexta-feira, 24 de junho de 2016 19:15

Todas as Respostas

  • Boa tarde,

    Não estou próximo a um computador agora para testar o código, mas teste trocar o parâmetro para:

    var modelo = {
    			"ItensAImportar": lstIntItens,
    			"OrcamentoId": $('#OrcamentoId').val(),
    			"Exercicio": $('#Exercicio').val(),
    			"InformadoPor": $('#InformadoPor').val()
    		};
    
    Espero ter ajudado

    Att,


    Se a resposta contribuiu com seu aprendizado por favor marque como util, se solucionou seu problema marque como resposta.

    sexta-feira, 24 de junho de 2016 17:14
  • Caro Silvaney,

    Não funcionou. 

    Grato pela sua atenção.

    Paulo Ricardo Ferreira

    sexta-feira, 24 de junho de 2016 17:35
  • Boa tarde,

    Coloque [Serializable] em cima da classe ImportarViewModel.
    [Serializable]
    public class ImportarViewModel
    {
    
    }



    Att,

    Se a resposta contribuiu com seu aprendizado por favor marque como util, se solucionou seu problema marque como resposta.

    sexta-feira, 24 de junho de 2016 17:38
  • Caro Silvaney,

    Ao tentar a sua sugestão o compilador já dá o erro abaixo:

    Error 2 Attribute 'Serializable' is not valid on this declaration type. It is only valid on 'class, struct, enum, delegate' declarations.

    Grato pela sua atenção.

    Paulo Ricardo Ferreira

    sexta-feira, 24 de junho de 2016 17:41
  • Boa tarde, Ricardo!

    Faça um teste trocando  data: JSON.stringify(modelo) por  data: modelo, no método Ajax.


    Att,
    Leandro

    Se foi útil, marque como útil ou como resposta.

    sexta-feira, 24 de junho de 2016 17:46
  • Caro Leandro,

    Também não funcionou.

    Grato pela sua atenção.

    Paulo Ricardo Ferreira.

    sexta-feira, 24 de junho de 2016 18:01
  • Ricardo,

    Conseguiu validar se o json está sendo enviado corretamente, se a url corresponde a action em questão?

    Para te ajudar com estes teste você pode utilizar o Fiddler, http://www.telerik.com/fiddler




    Att,
    Leandro

    Se foi útil, marque como útil ou como resposta.

    sexta-feira, 24 de junho de 2016 18:34
  • Caro Leandro,

    O que estou achando é que está dando algum problema no json enviado.

    Acho isso por conta de um teste que fiz. Na chamada do $.ajax, fiz uma pequena alteração do que é enviado.

    $.ajax({
         type: 'POST',
         url: '/Orcamento/Importar',
         dataType: 'json',
         data: JSON.stringify(lstIntItens),
         contentType: 'application/json;charset=utf-8',
         success: function () {
             window.location.href = "/Itens/Index/?ano=" + $('#Exercicio').val();
         },
         error: function (jqXHR, error, errorThrown) {
             mostraMensagem("Importação de itens", "erro", "Ocorreu um problema ao tentar importar os itens ('" + errorThrown + "')!");
         }
    });

    Alterei o que enviar para o controller. Passei a enviar tão somente a lista de int (lstIntItens). Aí o método é chamado.

    Acontece que preciso das outras informações. E o mais interessante é que nesse mesmo projeto eu tenho uma outra View que faz algo semelhante (passo um modelo complexo por json) e funciona corretamente. :-((

    Agora, como faria testes no telerik.com/fiddler?

    Grato pela sua atenção.

    Paulo Ricardo Ferreira


    sexta-feira, 24 de junho de 2016 18:44
  • Ricardo,

    Segue um link com uma explicação sobre o Fiddler: http://clienteweb.blogspot.com.br/2008/07/analisando-o-httpfiddler.html

    Mas já sabemos que o problema está no json, testa da seguinte maneira:

    JSON.stringify({ importarViewModel : modelo })


    Att,
    Leandro

    Se foi útil, marque como útil ou como resposta.

    sexta-feira, 24 de junho de 2016 19:04
  • Salve!

    Resolvi o problema alterando a classe que serve como model, ImportarViewModel. Retirei dela o construtor. Daí atribuí os seus valores no controller.

    Ficou assim:

    using ...
    namespace Estrutural.UI.ViewModels
    {
        public class ImportarViewModel
        {
            private DbEstrutural db = new DbEstrutural();
    
            public List<Item> LstItens { get; set; }
            public int Exercicio { get; set; }
            public int OrcamentoId { get; set; }
            public string InformadoPor { get; set; }
            public List<int> ItensAImportar { get; set; }
        }
    }

    Dessa forma o método é chamado com todas as informações que necessito.

    Grato pela atenção de todos.

    Paulo Ricardo Ferreira

    sexta-feira, 24 de junho de 2016 19:15