t

Comentários recentes

Exemplo de Custom Filter

Postado por Daniel Fonseca Castro - Tuesday, January 19, 2010 6:36 PM

Esse post fecha uma série de posts sobre Action Filter, segue os links dos posts anteriores.

Recursos para criação de Custom Filter
ASP.NET MVC – Action Filters
ASP.NET MVC – Entendendo os Actions Filters

Para facilitar a criação de um Custom Filter o time de desenvolvimento do framework ASP.NET MVC criou a classe abstrata ActionFilterAttribute essa classe implementa as interfaces IActionFilter, IResultFilter que já discutimos anteriormente, para construir esse exemplo vamos utilizar essa classe.

A implementação dos métodos dentro da classe ActionFilterAttribute utiliza o modificador virtual permitindo assim que você sobrescreva somente os métodos que você precisa para criação do seu Filter, veja a assinatura dos métodos da classe abaixo:

public virtual void OnActionExecuting(ActionExecutingContext filterContext) 
public virtual void OnActionExecuted(ActionExecutedContext filterContext) 
public virtual void OnResultExecuting(ResultExecutingContext filterContext) 
public virtual void OnResultExecuted(ResultExecutedContext filterContext)

Vamos criar um exemplo do zero, nesse exemplo vou criar uma aplicação simples e vou focar na criação do Filter,vamos criar uma aplicação de votação e o objetivo do nosso Filter será bloquear votos de um mesmo IP.

Criando a aplicação

No primeiro passo vamos criar um pequeno banco de dados para salvar os votos, veja a estrutura abaixo.

Banco de dados

Imagem 1 - Banco de dados.

Veja abaixo o código do repositório, para esse exemplo estou utilizando o EF.

public class VotoRepositorio 
{
    VotacaoEntities entidades = new VotacaoEntities();

    public void Salvar(Voto voto)
    {
        entidades.AddToVoto(voto);
        entidades.SaveChanges();
    }

    public IEnumerable<Voto> ObterTodos()
    {
        return (from votos in entidades.Voto
                select votos).AsEnumerable();
    }

    public IEnumerable<Voto> ObterIPUsuario(string ip)
    {
        return (from votos in entidades.Voto
                where votos.IPUsuario == ip
                select votos).AsEnumerable();
    }
}

Criando o Custom Filter

Agora podemos iniciar a criação do Filter veja o código abaixo.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class VotacaoFilterAttribute : ActionFilterAttribute
{
    VotoRepositorio votoRepositorio = new VotoRepositorio();

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        //Recupera IP do usuário
        var ip = filterContext.HttpContext.Request.ServerVariables["REMOTE_ADDR"];

        //Verifica se Action possui parâmetros
        if (filterContext.ActionParameters.Count > 0)
        {
            //Se não encontrar nenhum voto com o IP atual permite a execução da Action. 
            if (votoRepositorio.ObterIPUsuario(ip).Count() == 0)
            {
                //Recupera o parâmetro Voto da Action.
                Voto voto = filterContext.ActionParameters
                    .Where(x => x.Key == "voto").FirstOrDefault().Value as Voto;

                //Seta a propriedade IP.
                if (voto != null)
                    voto.IPUsuario = ip;
            }
            //Calcela a execução da Action caso já exista voto com IP atual
            else
            {
                filterContext.Result = new ContentResult()
                {
                    Content = String.Format("Esse IP: {0} já registrou um voto!", ip)
                };
            }
        }
    }
}

O código acima herda da classe ActionFilterAttribute e sobrescreve o método OnActionExecuting, o atributo AttributeUsage define que esse Filter pode ser utilizado somente em métodos e classes. O código do método OnActionExecuting recupera o IP do usuário e compara com todos os IPs cadastrados, caso o IP já possua um voto a seguinte mensagem será exibida no browser “Esse IP: xxx.xxx.xxx já registrou um voto!” e a execução da Action será cancelada , caso contrário recupero o objeto Voto e atualizo a propriedade IPUsuario.

Criando o Controller e as Views

Abaixo segue o código do Controller "Voto".

[HandleError]
public class VotoController : Controller
{
    VotoRepositorio votoRepositorio = new VotoRepositorio();

    public ActionResult Index()
    {
        //Mostra a View Index com todos os votos registrados.
        return View(votoRepositorio.ObterTodos());
    }

    public ActionResult Votar()
    {
        return View();
    }

    [VotacaoFilter]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Salvar(Voto voto)
    {
        //Salva voto e mostra a View Index com todos os votos registrados
        voto.DataVoto = DateTime.Now;
        votoRepositorio.Salvar(voto);
        return Redirect("Index");
    }
}

Note que a action Salvar foi "decorada" com o nosso Filter VotacaoFilterAttribute isso porque ela é a responsável por salvar os votos do usuário.

Para finalizar falta apenas construir duas Views, a "Index" que vai listar todos os votos cadastrados e a "Votar" que possui um formulário com as opções de voto, veja o código completo das duas views abaixo.

View Index.

Imagem 2 - Código da View Index.


View Votar

Imagem 3 - Código da View Votar.

Conclusão

Esse é um recurso extremamente poderoso que pode ser utilizado em vários cenários, sempre que você tiver um código que deve ser executado antes, durante ou depois da execução de uma Action você pode criar um Filter, a reutilização de código também é um ponto importante imagine colocar um if em todas as Action para fazer uma verificação comum, como por exemplo verificar se o usuário tem permissão, simplesmente horrível para evitar esse horror utilize os Filter e se não existir um que atenda a sua necessidade crie um!

Baixe o código fonte em C# ou VB.NET

Daniel Fonseca Castro

Currently rated 5.0 by 2 people

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

Categories: ASP.NET MVC

Related posts

Add comment


 

  Country flag