2009-04-17 12 views
6

Quando un utente effettua il login nella mia applicazione, voglio mostrare il suo nome nell'intera applicazione. Sto usando il framework MVC asp.net. Ma ciò che non voglio è che è avere a mettere in ogni cosa come regolatore:C# Centralizzazione ripetuta VIewData in MVC

ViewData["User"] = Session["User"]; 

Questo perché non si può ripetere se stessi. (Credo che questo sia il principio DRY [Do not Repeat Yourself] della programmazione OO.) ViewData ["User"] è sulla mia pagina principale. Quindi la mia domanda è, qual è un modo pulito per gestire il mio ViewData ["Utente"] in un posto?

risposta

12

È possibile farlo abbastanza facilmente in una classe di base del controller o in un filtro di azione applicato ai controller/azioni. In entrambi i casi, si ha la possibilità di toccare la richiesta prima (o dopo) dell'azione, quindi è possibile aggiungere questa funzionalità lì.

Ad esempio:

public class UserInfoAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(
     ActionExecutingContext filterContext) 
    { 
     base.OnActionExecuting(filterContext); 
     filterContext.Controller.ViewData["user"] = "Foo"; 
    } 
} 
... 
[HandleError, UserInfo] 
public class HomeController : Controller 
{...} 

(può essere usato anche alla() Livello metodo azione)


o con una base comune di classe:

public abstract class ControllerBase : Controller 
{ 
    protected override void OnActionExecuting(
     ActionExecutingContext filterContext) 
    { 
     ViewData["user"] = "Bar"; 
     base.OnActionExecuting(filterContext); 
    } 
} 

[HandleError] 
public class HomeController : ControllerBase 
{...} 
+0

Thnx, proverò la classe base. Ma perché sovrascrivere il metodo OnActionExecuting()? Cosa fa questo metodo? Qual è lo scopo? – Martijn

+0

Esegue appena prima che l'azione (metodo) venga eseguita. Se lo desideri, potresti probabilmente utilizzare OnActionExecuted, che viene eseguito immediatamente * dopo * l'esecuzione dell'azione. –

+0

OK, e poiché sto inserendo questo nella mia classe base, influisce su tutte le mie azioni all'interno del controller? – Martijn

2

Creare una classe base per i propri modelli con la proprietà UserName:

public abstract class ModelBase 
{ 
    public string UserName { get; set; } 
} 

Creare una classe base per i controller e sovrascrivere il metodo OnActionExecuted. All'interno controlla se il modello è abbandonato da BaseModel e, in caso affermativo, imposta la sua proprietà UserName.

public class ControllerBase : Controller 
{ 
    protected override void OnActionExecuted(
     ActionExecutedContext filterContext) 
    { 
     var modelBase = ViewData.Model as ModelBase; 

     if (modelBase != null) 
     { 
      modelBase.UserName = "foo"; 
     } 

     base.OnActionExecuted(filterContext); 
    } 
} 

allora si sarà in grado di visualizzare il nome utente di utenti nella vista in questo modo:

<%= Html.Encode(Model.UserName) %> 

Vedi anche:

+0

"controlla se il modello è abbandonato da BaseModel e .." come faccio? Puoi darmi un esempio? – Martijn

+0

@Martijn, aggiunto un esempio. –

+0

Penso di avere la soluzione. Ma non è un po 'complicato? Non fa la stessa classe base di Marc Gravell la stessa cosa in un certo senso? – Martijn

1

Un altro metodo per fornire i dati del modello persistenti attraverso fuori l'intera applicazione è sovrascrivendo il DefaultFactoryController con il tuo personalizzato. Nel tuo CustomerFactoryController, idraterai il ViewBag con il modello che desideri mantenere.

Problemi correlati