2009-04-17 17 views
6

Bir kullanıcı benim uygulamada oturum açtığında, tüm uygulama boyunca adını göstermek istiyorum. Asp.net MVC framework kullanıyorum.C# MVC'de yinelenen VIewData'nın merkezileştirilmesi

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

Bu kendini tekrar edemez, çünkü: Ama ne ben istemiyorum böyle her denetleyici bir şey koymak zorunda olmasıdır. (Bence bu, OO programlamanın KURUĞU [Kendini Yineleme] ilkesidir.) ViewData ["Kullanıcı"] ana sayfamda. Benim sorum şu ki, ViewData ["Kullanıcı"] 'yı tek bir yerde ele almanın düzgün bir yolu nedir?

cevap

12

Bunu bir denetleyici taban sınıfında veya denetleyicilere/eylemlere uygulanan bir eylem filtresinde oldukça kolay bir şekilde yapabilirsiniz. Her iki durumda da, işlemin öncesinde (veya sonrasında) isteğinize dokunma şansı elde edersiniz - böylece bu işlevselliği oraya ekleyebilirsiniz.

Örneğin

:

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

(aynı zamanda aksiyon (yöntemi) düzeyinde kullanılabilir)


ya da ortak bir taban sınıfı:

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

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

Thnx, temel sınıfı deneyeceğim. Ama neden OnActionExecuting() yöntemini geçersiz kılıyor? Bu yöntem ne yapar? Amacı nedir? – Martijn

+0

İşleminiz (yöntem) yürütülmeden hemen önce yürütülür. İsterseniz, muhtemelen eyleminizi gerçekleştirdikten sonra * hemen çalıştırılan OnActionExecuted'i kullanabilirsiniz. –

+0

Tamam, ve bunu temel sınıfıma yerleştirdiğim için, denetleyicideki eylemlerimi etkiler mi? – Martijn

2

ModelName özelliği ile modelleriniz için bir temel sınıf oluşturun:

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

Denetleyicileriniz için bir temel sınıf oluşturun ve OnActionExecuted yöntemini geçersiz kılın. İçinde modeli BaseModel'den derlenmiş olup olmadığını kontrol edin ve eğer varsa, UserName özelliğini ayarlayın.

+0

"modeli, modelin BaseModel'den olup olmadığını kontrol edin." Bunu nasıl yaparım? Bana bir örnek verebilirmisin? – Martijn

+0

@Martijn, bir örnek ekledi. –

+0

Sanırım çözümünüzü aldım. Ama ben biraz karmaşık değil miyim? Marc Gravell'in ortak temel sınıfı aynı şeyi bir şekilde yapmıyor mu? – Martijn

5

kadar oldu bir de:

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

See:

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); 
    } 
} 

Sonra böyle görünümünde kullanıcının UserName görüntülemek mümkün olacak yıl ama ben sadece acro tökezledim Bu soru ve ben daha iyi bir cevap olduğuna inanıyorum.

Jimmy Bogard bir anti-desen olarak kabul yanıt açıklandığı çözümü açıklar ve RenderAction kapsayan daha iyi bir çözüm sunmaktadır: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/18/the-filter-viewdata-anti-pattern.aspx

+0

+1. – Martijn

1
dışarı tüm uygulama üzerinden kalıcı modeli verilerini sağlamak için bir başka yöntem DefaultFactoryController ile geçersiz kılarak olduğunu

senin özel olan. CustomerFactoryController ürününüzde, ViewBag'i kalıcı olmasını istediğiniz modelle nemlendirirsiniz.