views:

729

answers:

3

I am using ASP.NET MVC for a project. I use a lot of User Control and I need to check the current user and the check if it has the roles etc, now I create the user in every UserControl I see the Permissions. I want to change that so I create it only once.

the Question is Whta is the best aproch? viewData["User"] = user and the get the user form here or what? what do you recomend so I can get rid of this lines

 LCP.eTorneos.Dal.EntityFramework.JugadorRepository jugadorRepository =
                   new LCP.eTorneos.Dal.EntityFramework.JugadorRepository();
 var jugador = jugadorRepository.GetJugador(User.Identity.Name)
 <% if (Page.User.Identity.IsAuthenticated && jugador.IsAdmin) { %>
      ...
 <%}%>
+2  A: 

There are 2 options. First, using ViewData["User"] - the simplest but not the best (not strongly typed). Second (if you are using View Models), using Base View Model for all your View Models:

public class BaseViewModel {
    public Jugador Jugador;

    // Or simply add flag

    public IsAdmin;
}

public class ConcreteViewModel : BaseViewModel {
    public YourModel Model;
}

In Controller:

var model = new ConcreteViewModel {
    Model = yourModel,
    IsAdmin = true /* false */
};

return View(model);

In Views:

<%@ Page MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ConcreteViewModel>" %>

<!-- Or in SiteMaster: -->

<%@ Master Inherits="System.Web.Mvc.ViewMasterPage<BaseViewModel>" %>

<% if(Model.IsAdmin) { %>

...

<% } %>

UPDATED:

It is better to avoid duplicating your code and setup the base part of ViewModel using custom filter:

public class IsAdminAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // ...

        (filterContext.Controller.ViewData.Model as BaseViewModel).IsAdmin = true; /* flase */
    }
}
eu-ge-ne
This works, but you realy have to make shure the role gets set in every controller. Once its is not done the value is taken from the request. Its nice to have it in a Filter.
Malcolm Frexner
Good point, I will update my answer
eu-ge-ne
@eu-ge-ne for what I understand this is the right direction but I have a question, this filter go in the controller, how do I get this info in the view so I can decide to show a link or not for example?
Jedi Master Spooky
The filter deals with the Model right after Action creates it and fill with data. Then Your filter's OnActionExecuted() method fires and sets IsAdmin property. Then your ViewModel goes to the View (your Views must be strongly-typed with ViewModelBase or class derived from ViewModelBase), where you can use Model.IsAdmin property
eu-ge-ne
check My solution, let me know what you think
Jedi Master Spooky
+1  A: 

First of all Thanks @eu-ge-ne.

This I what I did, I am open to new suggestions but this seems to work: I create a ActionFilterAttribute like this:

 public class JugadorAttribute : ActionFilterAttribute {
    public override void OnActionExecuted(ActionExecutedContext filterContext) {
        JugadorRepository jugadorRepository = new JugadorRepository();
        Jugador jug = jugadorRepository.GetJugador(filterContext.HttpContext.User.Identity.Name);
        filterContext.Controller.ViewData["JugadorActual"] = jug; 
    }
}

This put in ViewData the current Player of the Page. Then in my controller I do this:

 [JugadorAttribute()]
public class HomeController : Controller {

The Problem now Is that ViewData is not strong typed so I create this helper in the Html class:

 public static class JugadorHelper {
    public static Jugador GetJugador(this HtmlHelper html) {
        return ((LCP.eTorneos.Dal.EntityFramework.Jugador)html.ViewData["JugadorActual"]);
    }
}

And Whoala, now I can do this in my views:

Html.GetJugador().IsAdmin
Jedi Master Spooky
I have one suggestion. I think HtmlHelper is not right place for GetJugador extension (HtmlHelper extensions deal only with creating HTML markup). Rather create static Utility class with method: Jugador GetJugador(ViewDataDictionary ViewData) { return ViewData["JugadorActual"] as Jugador; }.
eu-ge-ne
+1  A: 

I believe that something like this:

<%= Utils.GetJugador(ViewData).IsAdmin %>

is much better than this:

<%= Html.GetJugador().IsAdmin %>

because HtmlHelper extensions are only for generating HTML markup

UPDATE:

using System.Web.Mvc;
using LCP.eTorneos.Dal.EntityFramework;

public static class Utils {
    public static Jugador GetJugador(ViewDataDictionary ViewData) {
        return ViewData["JugadorActual"] as Jugador;
        /* OR maybe ?
         * return (Jugador)(ViewData["JugadorActual"] ?? new Jugador());
         */
    }
}

Hope this helps

eu-ge-ne