none
Forma correta de fazer validações na View RRS feed

  • Pergunta

  • Olá,

    tenho nas minhas view o botão "Inserir", e logo abaixo o grid com os dados. Mas conforme o perfil do usuário, ele não pode inserir nada, então queria não mostrar o botão para este usuário. Qual a sugestão de vocês para validar se mostra ou não o botão na view.

    Utilizar ViewBag é a solução? Ou tem outro jeito mais elegante?

    Abs


    Marlon Tiedt
    www.sesmt.com.br

    quarta-feira, 10 de outubro de 2012 16:35

Todas as Respostas

  • Você pode colocar no ViewModel:

    public class HomeViewModel
    {
         public bool UserHasPermissionToInsert {get; set;}
    }

    e na view:

    @model HomeViewModel
    
    @if(Model.UserHasPermissionToInsert){
    //mostra o botão
    }


    http://www.linkedin.com/pub/murilo-kunze/44/191/455

    quarta-feira, 10 de outubro de 2012 16:40
  • Tem várias maneiras.

    Uma dela é verificar se o usuário está em um determinado perfil:
    @if(UserIsInRole("SeuPerfil"))

    Não utilizaria ViewBag para trafegar este tipo de informação. Na verdade, faria uma view separada para criação, assim ela fica isolada, sem o mínimo risco do usuário conseguir criar algo.

    Evite "desabilitar (DISABLED)" os controles na tela, pois o usuário pode abrir as ferramentas de desenvolvedor e editar o HTML, tornando o botão habilitado.

    Me diz meio por cima o que quer fazer que talvez possa te orientar melhor.

    Abraços,


    Se sua questão foi respondida, favor marcar.

    André Baltieri
    MTAC – Microsoft Technical Audience Contributor

    Twitter: @andrebaltieri
    Blog: http://andrebaltieri.net
    Site: http://sismat.com.br

    quarta-feira, 10 de outubro de 2012 17:13
  • Olá,

    a ideia é assim, na pagina index do controller, por padrão vai ter o botão inserir no topo, e depois a lista de dados do controller.
    Eu queria fazer uma regra no controller e este passar para a view, se pode ou não mostrar o botão inserir.

    Fiz assim por enquanto:

    Contoller

    public ActionResult Index()
    {
      ViewBag.MostarInsert = false; // Fixo somente para teste, depois irei fazer um helper
      return View();
    }

    View:

    @{
        ViewBag.Title = "Index";
        if (ViewBag.MostarInsert)
        {
            <div class="linha">
                @Html.ActionLink("Inserir", "Inserir", null, new { @class = "botao_inserir_icone_32x32_grande" })	
            </div>
        }
    }
    

    Melhorou?

    tks

    Marlon Tiedt
    www.sesmt.com.br

    quarta-feira, 10 de outubro de 2012 18:06
  • public class InsertViewModel{
         public bool MostrarInsert{get;set;}
    }

    Action:

    public ActionResult Index()
    {
         return View(new InsertViewModel{
            MostrarInsert = false;
         });
    }

    View:

    @model InsertViewModel
    
    @{if (Model.MostarInsert)
        {
            <div class="linha">
                @Html.ActionLink("Inserir", "Inserir", null, new { @class = "botao_inserir_icone_32x32_grande" })	
            </div>
        }
    }

    http://www.linkedin.com/pub/murilo-kunze/44/191/455


    • Editado Murilo Kunze quarta-feira, 10 de outubro de 2012 18:25
    quarta-feira, 10 de outubro de 2012 18:21
  • Marlon, eu ainda concordo com a idéia do André Baltieri, não adianta ocultar, pois usuario pode habilitar por html, sendo assim podendo usar o botão. Aconselho você mostrar botão, porem tirar acesso, assim evitando dor de cabeça mais pra frente!

    quarta-feira, 10 de outubro de 2012 18:31
  • Wescley,

    você acha melhor deixar o botão lá, e tratar diretamente no action do inserir?
    E se fazer as duas ações?

    Pois assim não ficaria aquela conversa do usuário, o botão está lá, mas eu não tenho acesso, então não deveria estar... :)

    tks pelas respostas

    Abs

    Marlon Tiedt
    www.sesmt.com.br

    quarta-feira, 10 de outubro de 2012 18:37
  • Não importa se ele pode habilitar ou não.. esse tratamento de poder inserir ou não de qualquer forma deve existir na camada de negra de negócio.. isso é independente do que tem na sua view.

    http://www.linkedin.com/pub/murilo-kunze/44/191/455

    quarta-feira, 10 de outubro de 2012 18:37
  • Não Marlon, você pode remover o botão mas de qualquer forma você deve tratar os dados no POST.

    http://www.linkedin.com/pub/murilo-kunze/44/191/455

    quarta-feira, 10 de outubro de 2012 18:39
  • se ele pode habilitar, pra que esconder? o.O

    mais fácil vc trazer habilitado e mostro pro usuário que ali tem uma opção, porem ele não pode ter acesso, do que ele entrar e não ve nenhum botão e fala que sistema tem problema.

    outra coisa é você desabilitar o botão, cara habilitar e clicar nele, e depois vc tem que fica tratando isso!

    quarta-feira, 10 de outubro de 2012 18:44
  • Então a sugestão de vocês é, deixa sempre lá, visivel e habiltado e tratar diretamente no controlker...

    Pois ele também pode tentar acesso direto pela URL, ai ferrou...

    abs

    Marlon Tiedt
    www.sesmt.com.br

    quarta-feira, 10 de outubro de 2012 18:47
  • Wesley, todo html no cliente é editavel cara.. sendo assim o cliente faz o que ele quiser.. se ele quiser criar campos a mais, ele pode..

    A questão é que os dados enviados para o servidor(através do POST) DEVEM SEMPRE ser validados..

    Agora se o cliente editar o seu html e criar um botão que faz um post para a sua action, não vai ter problema pois existe a validação..


    http://www.linkedin.com/pub/murilo-kunze/44/191/455

    quarta-feira, 10 de outubro de 2012 18:48
  • Marlon... todo seu código deve ser tratado... o que você vai exibir para o cliente não importa.. Se você deixa habilitado o botão ou não não importa!!

    Se você acha que o cliente vai gostar de ver um botão desabilitado, então deixe.. caso contrário tire.. mas INDEPENDENTE DISSO você deve validar a permissão dele no POST.


    http://www.linkedin.com/pub/murilo-kunze/44/191/455

    quarta-feira, 10 de outubro de 2012 18:51
  • Olá Murilo, como estou vindo do mundo Delphi, este xunxos do cliente eu não sabia que o cara poderia fazer...

    Para esta validação, o ModelState.IsValid, já é suficiente, ou existe uma forma melhor?

    Abs

    Marlon Tiedt
    www.sesmt.com.br

    quarta-feira, 10 de outubro de 2012 18:52
  • Marlon, o ModelState vai validar se os campos enviados para a action estão corretos(se estão preenchidos por exemplo)..

    Mas a validação de inserção de dados no banco é diferente..

    Como você está fazendo as validações?

    Normalmente você coloca esse tipo de validação na camada de regra de negócio.


    http://www.linkedin.com/pub/murilo-kunze/44/191/455

    quarta-feira, 10 de outubro de 2012 18:55
  • Sigo este padrão:

    [HttpPost]
    public ActionResult Inserir(EPI model)
    {
        if (ModelState.IsValid)
        {
            CamposGenericos.AtribuirValores(model, "I");
    
            db.EPI.Add(model);
            db.SaveChanges();              
            return RedirectToAction("Index", "Home");
        }
        ViewBag.ListaSubGrupo = new SelectList(db.EPISubGrupo.ToList(), "SubGrupoID", "Sigla");
        return View(model);
    }

    abs

    Marlon Tiedt
    www.sesmt.com.br

    quarta-feira, 10 de outubro de 2012 19:04
  • Então você pode usar a validação de model do entity:

    http://stackoverflow.com/questions/3400542/how-do-i-use-ivalidatableobject

    Eu gosto de usar uma camada para validação: http://www.asp.net/mvc/tutorials/older-versions/models-(data)/validating-with-a-service-layer-cs

    Ai nessa camada você valida se o usuário que está inserindo tem permissão.


    http://www.linkedin.com/pub/murilo-kunze/44/191/455


    • Editado Murilo Kunze quarta-feira, 10 de outubro de 2012 19:12
    quarta-feira, 10 de outubro de 2012 19:10
  • Você tem um permissionamento, certo?

    O usuário só pode inserir se ele estiver em um determinado perfil, procede?
    Se estiver utilizando Membership, usa o que te falei e em adicional coloca o filtro no controller

    na sua view fica assim
    @If(User.IsInRole("Administrador")) { Mostra botão }

    No seu controller, no create você pode usar o Authorize action filter para garantir que nada que saiu de lá vai passar no Create com outro perfil

    [Authorize(Roles="Administrador")]
    [HttpPost]
    public ActionResult Create(...

    Pode usar no GET do Create também.

    Em adicional, no ASP.NET MVC 4 foi incluso um método anti-forgery para garantir que não vai ter injeção de post no seu controller. Caso seja uma app que vá pra internet por exemplo e você não queira deixar nenhuma brecha, pode dar uma olhada aqui:
    http://msdn.microsoft.com/en-us/library/system.web.mvc.htmlhelper.antiforgerytoken(v=vs.108).aspx

    Eu não gosto muito de ficar enxendo Views de IF, mas neste caso, não acho legal deixar um botão "Inserir" sendo que o usuário não pode inserir, concorda?

    Abraços,


    Se sua questão foi respondida, favor marcar.

    André Baltieri
    MTAC – Microsoft Technical Audience Contributor

    Twitter: @andrebaltieri
    Blog: http://andrebaltieri.net
    Site: http://sismat.com.br

    quarta-feira, 10 de outubro de 2012 21:16
  • Eu também gosto dessa idéia Murilo,

    Há um tempo publiquei uma série com 3 artigos no TechNet Wiki sobre isso
    http://social.technet.microsoft.com/wiki/contents/articles/7324.desenvolvendo-aplicacoes-para-diferentes-cenarios-com-asp-net-mvc-e-ef-parte-1-pt-br.aspx

    Abraços,


    Se sua questão foi respondida, favor marcar.

    André Baltieri
    MTAC – Microsoft Technical Audience Contributor

    Twitter: @andrebaltieri
    Blog: http://andrebaltieri.net
    Site: http://sismat.com.br

    quarta-feira, 10 de outubro de 2012 21:17
  • Olá,

    nossa estou com um nó na cabeça...huahauah...

    Vou responder e re-perguntar por partes, vamos lá:

    1 - Validação de model do entity, eu vi, mas não entendi direito para que server
    2 - Se usar 
    User.IsInRole, não terá como o usuário injetar códigos para fazer xunxo, é isto?
    3 - Tem como eu usar um 
    AuthorizeAttribute dentro da View? Acho que desta maneira, seria parecida com o IsInRole, certo?

    Desculpa algumas perguntas bobas, porém, estou querendo entender C# e não somente copiar e colar códigos...

    tks



    Marlon Tiedt
    www.sesmt.com.br

    quinta-feira, 11 de outubro de 2012 00:03