2009-04-17 10 views
6

Kiedy użytkownik loguje się do mojej aplikacji, chcę pokazać jego imię w całej aplikacji. Korzystam z ramy asp.net MVC. Ale to, czego nie chcę, to to, że trzeba umieścić w każdym kontrolerze coś takiego:C# Centralizacja powtarzania VIewData w MVC

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

to dlatego, że nie może powtórzyć się. (Wierzę, że jest to zasada DRY [Do not Repeat Yourself] programowania OO.) ViewData ["User"] znajduje się na mojej masterpage. Moje pytanie brzmi: jaki jest przyjemny sposób obsługi mojego ViewData ["User"] w jednym miejscu?

Odpowiedz

12

Możesz to zrobić dość łatwo w klasie kontrolera lub w filtrze akcji, który jest stosowany do kontrolerów/akcji. W obu przypadkach masz szansę dotknąć prośby przed (lub po) akcją - możesz więc dodać tę funkcję tam.

Na przykład:

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

(może być również stosowany w poziomie działania (metoda))


lub wspólnej podstawy klasy:

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

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

Thnx, spróbuję klasy bazowej. Ale dlaczego przesłonić metodę OnActionExecuting()? Co robi ta metoda? Jaki jest cel? – Martijn

+0

Wykonuje się tuż przed wykonaniem akcji (metody). Jeśli chcesz, możesz prawdopodobnie użyć OnActionExecuted zamiast tego, który wykonuje się natychmiast * po * wykonaniu twojej akcji. –

+0

OKay, i ponieważ umieszczam to w mojej klasie bazowej, wpływa to na moje działania w kontrolerze? – Martijn

2

Utwórz klasę podstawową dla modeli z właściwością UserName:

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

Utwórz klasę podstawową dla kontrolerów i zastąp jej metodę OnActionExecuted. W jego ramach sprawdź, czy model został wykreślony z BaseModel, a jeśli tak, ustaw jego właściwość 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); 
    } 
} 

Wtedy będziesz w stanie wyświetlić USERNAME w widoku jak ten:

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

Zobacz także:

+0

"sprawdź, czy model został wykreślony z BaseModel i ..." jak to zrobić? Czy możesz podać mi przykład? – Martijn

+0

@Martijn, dodano przykład. –

+0

Myślę, że dostaję twoje rozwiązanie. Ale czy nie jest to trochę skomplikowane? Czy w pewnym sensie nie robi wspólnej klasy bazowej Marca Gravella? – Martijn

1

Innym sposobem na zapewnienie trwałych danych modelowych poprzez swoje całej aplikacji jest poprzez nadpisanie DefaultFactoryController z twój niestandardowy. W swoim CustomerFactoryController uwadniasz ViewBag z modelem, który chcesz utrwalić.

Powiązane problemy