t
  • Entreguei o primeiro projeto em #WRT gastei mais tempo configurando o ambiente do que desenvolvendo! A #nokia poderia melhorar isso..

Posts recentes

Comentários recentes

Olho aberto com o ModelBinder

Postado por Daniel Fonseca Castro - Saturday, April 17, 2010 8:20 AM
chefe-em-cima-da-mesa

O ModelBinder e um facilitador ele é quase “mágico”, mais você precisa ficar de olho aberto para evitar problemas, vamos imaginar um cenário. O portal da empresa aonde você trabalhar tem uma área de eventos super importante, é os usuários podem comentar os eventos, claro os comentários são moderados para evitar piadinhas,ofensas ,palavrões e qualquer coisa que possa incomodar a empresa.

Em um belo dia de repente alguns comentários ofensivos começam aparecer no portal da empresa sem a aprovação de ninguém e para desespero do desenvolvedor e fúria do gerente ninguém sabe como isso aconteceu! Vamos ver como isso pode acontecer com um exemplo,veja o modelo abaixo.

modelo-entity-framework

Imagem 1 - Modelo de exemplo

Não existe nenhum problema com o modelo acima, note que na entidade Comentario a propriedade booleana "Aprovado" indica se o seu conteúdo pode ou não ser exibido no portal, vamos ver como isso ficaria na View.

trecho-codigo-view-comentario

Imagem 2 -Trecho que exibe comentários aprovados

A View acima recebe como Model um objeto "Evento" que contém uma lista de objetos "Comentarios" , somente os comentários com a propriedade "Aprovado" igual a true são exibidos. Agora vamos analisar o trecho de código da View que adiciona comentário.

trecho-codigo-view-adiciona-comentario

Imagem 3 -Trecho que adiciona comentário

Um formulário super simples com dois inputs um hidden com o Id do evento e um TextArea para o comentário, por fim vamos analisar a Action.

[HttpPost]
public ActionResult NovoComentario(Comentario comentario)
{
    if (ModelState.IsValid)
    {
        eventoRepositorio.NovoComentario(comentario);
    }
    return RedirectToAction("Details", new { id = comentario.Eventos.IdEvento });
}

A Action "NovoComentario" recebe um objeto "Comentario" criado pelo ModelBinder, e simplesmente verifica se o ModelState é valido antes de persiste o objeto.vamos analisar o objeto Comentario.

quick watch

Nenhum problema certo? A descrição foi preenchida normalmente a flag Aprovado esta com o valor correto para um novo comentário que é false e o id do evento também foi preenchido sem maiores problemas! Mais o que acontece se eu receber um input de qualquer tipo com o name igual a "Aprovado" e com o value igual a true?

Se isso acontecer você terá um problemão para resolver!

Porque o ModelBinder vai criar um objeto “Comentario” com a propriedade “Aprovado” igual a true e conseqüentemente esse comentário será exibido no portal sem a aprovação de ninguém, adicionar mais um parâmetro em uma solicitação HTTP é uma tarefa relativamente simples,você pode utilizar uma ferramenta para fazer isso , o Fiddler ou Charles são duas opções, legal identificamos o problema da Action "NovoComentario" mais como resolve-lo?

Para resolver esse problema você deve utilizar o BindAttribute, ele controla o comportamento do ModelBinder definindo o que deve ou não ser preenchido.Esse atributo possui três propriedades Exclude,Include e Prefix.

Exclude: contém uma lista com os nomes das propriedades que devem ser ignoradas, essa lista é separada por vírgula.

Include: inclui uma lista com os nomes das propriedades que devem ser preenchidas, essa lista é separada por vírgula.

Prefix: contém um prefixo que deve ser adicionado aos nomes dos inputs.

O BindAttribute pode ser utilizado como atributo de classe ou como parâmetro, para o nosso problema podemos utiliza o Bind como parâmetro na Action "NovoComentario" excluindo a preenchimento da propriedade "Aprovado".

[HttpPost]
public ActionResult NovoComentario([Bind(Exclude = "Aprovado")]Comentario comentario)
{
    if (ModelState.IsValid)
    {
        eventoRepositorio.NovoComentario(comentario);
    }

    return RedirectToAction("Details", new { id = comentario.Eventos.IdEvento });
}

Medida simples para grandes problemas! Feito isso o ModelBinder vai ignorar qualquer input com o nome Aprovado,para testar esse comportamento você pode adicionar um input hidden dentro do form.

<%= Html.Hidden("Comentario.Aprovado", true)%>

Você pode executar o projeto sem o atributo Bind e depois com ele para perceber a diferença, com o atributo ele simplesmente ignora o input hidden “Aprovado” que foi adicionado na pagina, é se um usuário maldoso adicionar um parâmetro a solicitação com o intuito de burlar a moderação dos comentários esse parâmetro também será ignorado.

Baixe o fonte em C# ou VB.NET

Daniel Fonseca Castro

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: ASP.NET MVC | ASP.NET MVC 2

Related posts

  • Bruno
    Bruno
    19 May 2010 10:20 PM
    Muito bom parabens.

Add comment


 

  Country flag