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

Em relação a [ValidateAntiForgeryToken]

No exemplo da vídeo aula, o professor acrescenta o [ValidateAntiForgeryToken] antes do método Form, porém eu tentei acrescentar em outros métodos desta mesma classe, como: Form, Adiciona, Decrementa e etc. E foi dando erro tanto no Adiciona quanto no Decrementa, mesmo eu acrescentando no formulário respectivo o comando @Html.AntiForgeryToken(). Tem alguma regra para que este par de comandos funcionem? Só funciona quando temos um form?

7 respostas

Olá, Vanessa! Quais erros aparecem no console? Pode colar aqui para podermos analisar melhor? Obrigado!

Na url = http://localhost:51270/produtos/2

Mensagem de Erro = Erro de Servidor no Aplicativo '/'.

The required anti-forgery form field "__RequestVerificationToken" is not present.

Código: Na View:

@Html.AntiForgeryToken()

Id: @ViewBag.Produto.Id <br />
Nome: @ViewBag.Produto.Nome <br />
Quantidade: @ViewBag.Produto.Quantidade <br />
Preço: @ViewBag.Produto.Preco <br />
<p>@Html.ActionLink("Voltar para a Lista", "Index", "Produto")</p>
<p>@Html.RouteLink("Voltar para a Lista", "ListarProdutos")</p>

Código: Na Controller:

        [Route("produtos/{id}", Name = "VisualizarProdutos")]
        [ValidateAntiForgeryToken]
        public ActionResult Visualiza (int id)
        {
            ProdutosDAO dao = new ProdutosDAO();
            Produto produto = dao.BuscaPorId(id);
            ViewBag.Produto = produto;
            return View();

        }

Deduzi que o problema era porque a View que vizualiza os dados não possui um form, pois o exemplo do professor é dentro do form. Não tem nada haver? :(

Este comando [ValidateAntiForgeryToken] é o único exercício que não consegui fazer neste curso. O restante está tudo entendido, testado e funcionando.

Pode ter relação com este código comentado abaixo?

Arquivo FilterConfig.cs:

namespace CaelumEstoque.App_Start
{
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            //filters.Add(new AutorizacaoFilterAttribute());
        }
    }
}

Arquivo AutorizacaoFilterAttribute.cs

namespace CaelumEstoque.Filtros
{
    public class AutorizacaoFilterAttribute   : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            //base.OnActionExecuting(filterContext);
            object usuario = filterContext.HttpContext.Session["usuarioLogado"];
            if (usuario == null)
            {
                filterContext.Result = new RedirectToRouteResult(
                    new RouteValueDictionary(
                        new { controller = "Login", action = "Index" }
                    )
                );
            }
        }
    }
}

Arquivo Global.asax

namespace CaelumEstoque
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        }
    }
}
solução!

Exato, Vanessa, o método da action Visualiza recebe um HTTP GET e por isso não precisa de ValidateAntiForgeryToken, pois ele não é usado para alterar um valor do sistema. Somente nas requisições POST, em que você envia dados, por exemplo, de um novo cadastro de produto ou altera os dados de produtos preexistentes no sistema. Resumindo: use o token apenas para inserir/alterar dados, nunca para obtê-los. Obrigado por participar do fórum e parabéns por ter feito os exercícios do curso com sucesso! Boa sorte e bons estudos!

Marcelo, Obrigada. Porém, ainda assim, não funcionou. Retirei o ValidateAntiForgeryToken dos métodos Visualiza, Form e Index, e mantive apenas no método Adiciona, pois este método insere no banco de dados. Mesmo assim, recebo erro no Adiciona. (url: http://localhost:51270/produtos/4) Mensagem de erro: -Erro de Servidor no Aplicativo '/'.

The required anti-forgery form field "__RequestVerificationToken" is not present.

Descrição: Ocorreu uma exceção sem tratamento durante a execução da atual solicitação da Web. Examine o rastreamento de pilha para obter mais informações sobre o erro e onde foi originado no código.

Detalhes da Exceção: System.Web.Mvc.HttpAntiForgeryException: The required anti-forgery form field "__RequestVerificationToken" is not present.

Erro de Origem:

Exceção sem tratamento foi gerada durante a execução da atual solicitação da Web. As informações relacionadas à origem e ao local da exceção podem ser identificadas usando-se o rastreamento de pilha de exceção abaixo.

Segue o meu código: View:

<form action="/Produto/Adiciona" method="post">
    @Html.AntiForgeryToken()
    @Html.ValidationMessage("produto.InformaticaComPrecoInvalido")

    <label for="nome">Nome:</label>
    <input id="nome" name="produto.Nome" value="@ViewBag.Produto.Nome" class="form-control"/>
    @Html.ValidationMessage("produto.Nome")

    <label for="preco">Preço:</label>
    <input id="preco" name="produto.Preco" value="@ViewBag.Produto.Preco" class="form-control"/>
    @Html.ValidationMessage("produto.Preco")

    <label for="quantidade">Quantidade:</label>
    <input id="quantidade" name="produto.Quantidade" value="@ViewBag.Produto.Quantidade" class="form-control"/>

    <label for="descricao">Descrição:</label>
    <input id="descricao" name="produto.Descricao" value="@ViewBag.Produto.Descricao" class="form-control"/>

    <label for="categoria">Categoria:</label>
    <select id="categoria" name="produto.CategoriaId" class="form-control" >
        @foreach (var categoria in ViewBag.Categorias)
        {
            <option value="@categoria.Id" selected="@categoria.Id.Equals(ViewBag.Produto.CategoriaId)">
                @categoria.Nome
            </option>
        }
    </select>

    <input type="submit" />

    <p>@Html.ActionLink("Voltar para Produto", "Index", "Produto")</p>
</form>

Código: ProdutoController :

  [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Adiciona(Produto produto)
        {
            // implementação da action
            //ProdutosDAO dao = new ProdutosDAO();
            //dao.Adiciona(produto);
            //return View();

            int idDaInformatica = 1;
            if (produto.CategoriaId.Equals(idDaInformatica) && produto.Preco < 100)
            {
                ModelState.AddModelError("produto.InformaticaComPrecoInvalido", "Produtos da categoria informática devem ter preço maior do que 100");
            }
            if (ModelState.IsValid)
            {
                ProdutosDAO dao = new ProdutosDAO();
                dao.Adiciona(produto);
                return RedirectToAction("Index");
            }
            else
            {
                CategoriasDAO categoriasDAO = new CategoriasDAO();
                ViewBag.Categorias = categoriasDAO.Lista();
                return View("Form");
            }
        }

[RESOLVIDO este erro também] Pelo que estou testando... o meu erro não tem relação com o ValidateForget, mas com algo relacionado com ValidationMessage.

Só não estou entendendo onde ou porque?

An exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException' occurred in System.Core.dll but was not handled in user code

Additional information: Não é possível fazer associação em tempo de execução em uma referência nula