Solucionado (ver solução)
Solucionado
(ver solução)
14
respostas

Problema para cadastrar novo produto

Olá! Depois das alterações feitas com as rotas, eu não consegui mais cadastrar novos produtos, sempre que clico em cadastrar, aparece o seguinte erro:

Erro de Servidor no Aplicativo '/'.

The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Visualiza(Int32)' in 'CaelumEstoque.Controllers.ProdutosController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Nome do parâmetro: parameters

Eu tive o mesmo problema em outra View (Form dos produtos) e foi resolvido quando eu criei um Route para o método public ActionResult Form() ([Route("produtos/adicionar", Name = "AdicionaProduto")]). Mas no caso do método Adiciona() eu não consegui resolver, eu até criei um Route para ele, mas na tag <form> eu não consigo colocar o RouteLink como Action para tentar resolver o problema. Alguém pode me ajudar?

14 respostas

Oi Hudson,

Você disse em cadastrar? O erro está apontando para o método Visualiza. Tem certeza que a rota está correta para esse método?

Arthur, perdão pela demora ao responder! Então, o problema é na hora de cadastrar mesmo! E eu não sei porque aparece o problema no Visualiza. Meu código está assim: No form

<form action="/Produtos/Adiciona" method="post">

Método adiciona

[HttpPost] 
        public ActionResult Adiciona(Produto produto)
        {
            EstoqueContext context = new EstoqueContext();
            var busca = context.Categorias.FirstOrDefault(id => id.Nome.Contains("Informática"));
            int idInfo = busca.Id;

            if(produto.CategoriaId == idInfo && produto.Preco < 100)
            {
                ModelState.AddModelError("produto.InformaticaComPrecoInvalido", "O preço da categoria informática deve ser de, no mínimo, 100");
            }



            if (ModelState.IsValid)
            {
                ProdutosDAO dao = new ProdutosDAO();
                dao.Adiciona(produto);
                return RedirectToRoute("ListaProdutos");

            }
            else
            {
                CategoriasDAO categoriasDAO = new CategoriasDAO();
                ViewBag.Categorias = categoriasDAO.Lista();
                ViewBag.Produto = produto;
                return View("Form");


            }


        }

Lista produtos

[Route("produtos", Name = "ListaProdutos")]
        public ActionResult Index()
        {

            ProdutosDAO dao = new ProdutosDAO();
            IList<Produto> produtos = dao.Lista();


            return View(produtos);
        }

Hudson,

Você consegue saber se o seu código está chegando ao seu método Adiciona corretamente?

Colocando um breakpoint na primeira linha dentro do seu método e executando o projeto no modo debug, o breakpoint é ativado?

Não chega a executar! O engraçado é que o mesmo problema do Visualiza acontece quando eu tento entrar na URL pelo nome da Action e não pelo Route (ex: /Produtos/Form ao invés de /produtos/adicionar). E quando eu clico no "Cadastrar" ele vai pra URL /Produtos/Adiciona

No método Adiciona eu tentei colocar um Route("produtos/adicionar/ok", Name = "AdicionaOk") para testar, mas no <form> eu não consegui colocar um Route para executar

Eu fiz uma View só para teste e sem Route nela, tentei executar e deu esse problema do Visualiza (???). Aparentemente as coisas só funcionam se elas tiverem Route, senão elas dão esse erro no Visualiza que não tem nada a ver (ao menos aparentemente)

Hudson,

Faz um teste pra mim...remova a regra de Routing de todos os métodos e links. Use o método padrão de acesso e tente novamente.

Comentei todos os Routes no ProdutosController e voltou a funcionar normalmente, Arthur! Agora não sei se isso é bom ou ruim hahaha

Eu me lembro que o routing valida os links com argumentos. Acho que é isso que aconteceu com o link do Visualiza que recebe um ID e dá o erro de nulo.

Então qual seria a melhor correção para isso? Já que aparentemente é impossível trabalhar desse jeito

Como que estava o route para o método Visualiza?

Assim:

[Route("produtos/{id}", Name = "VisualizaProduto")]
        public ActionResult Visualiza(int id)
        {

            ProdutosDAO dao = new ProdutosDAO();
            Produto produto = dao.BuscaPorId(id);
            ViewBag.Produto = produto;
            return View();
        }
solução!

Hudson,

Descobri o problema. Quando você coloca assim:

[Route("produtos/{id}", Name = "VisualizaProduto")]

Isso significa que para entrar na visualização você usa a URL de exemplo:

http://localhost:99999/produtos/1

Agora, vamos ver a URL para adicionar um produto:

http://localhost:99999/produtos/Adiciona

Note que as URLS têm o mesmo formato!!! Ou seja, o .NET está interpretando a URL do Adiciona como se fosse de Visualização!!!

Isso é muito arriscado!!!

Sugiro você mudar o routing da visualização para:

[Route("produtos/Visualiza/{id}", Name = "VisualizaProduto")]

Assim, para visualizar um produto você deve usar a URL:

http://localhost:99999/produto/Visualiza/1

Dessa forma, não há o conflito entre URLs!!!

Arthur, muuuuito obrigado! Funcionou perfeitamente. Eu jamais pensaria que ele estaria recebendo o parâmetro no Adiciona. Valeu \o/

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software