2012-07-31 28 views
4

我有一個自定義的模型綁定器,它檢查身份驗證cookie並返回值。如何將值傳遞給MVC3母版頁(_layout)?

public class UserDataModelBinder<T> : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 

     if (controllerContext.RequestContext.HttpContext.Request.IsAuthenticated) 
     { 
      var cookie = 
       controllerContext.RequestContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName]; 

      if (cookie == null) 
       return null; 

      var decrypted = FormsAuthentication.Decrypt(cookie.Value); 

      if (!string.IsNullOrWhiteSpace(decrypted.UserData)) 
       return JsonSerializer.DeserializeFromString<T>(decrypted.UserData); 
     } 

     return null; 
    } 
} 

如果我需要使用它,我只需要將它傳遞給動作即可。一切正常。

public ActionResult Index(UserData userData) 
{ 
    AccountLoginWidgetVM model = new AccountLoginWidgetVM(); 
    if (null != userData) 
     model.UserData = userData; 

    return View(userData); 
} 

不過,我想用它在我的母版頁,因爲一旦用戶登錄,我想展示自己在每個頁面頂端的信息。我嘗試了一些東西,coudln't得到它的工作

@Html.RenderPartial("LoginPartial", ???model here??) 
+0

您是否在視圖中包含了模型聲明? – Yasser 2012-07-31 12:24:57

回答

11

我們做到了,如下所示:

  1. 爲masterpages定義單獨視圖模型。

    public class MasterPageViewModel 
    { 
        public Guid CurrentUserId { get; set; } 
        public string CurrentUserFullName { get; set; } 
    } 
    
  2. 添加了注射過濾器和過濾器提供者。

    public class MasterPageViewModelInjectorFilterProvider: IFilterProvider 
    { 
        public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 
        { 
         return new [] {new Filter(new MasterPageViewModelInjectorFilter(), FilterScope.Action, null), }; 
        } 
    
        private class MasterPageViewModelInjectorFilter: IResultFilter 
        { 
         public void OnResultExecuting(ResultExecutingContext filterContext) 
         { 
          var viewResult = filterContext.Result as ViewResult; 
          if (viewResult == null) 
           return; 
    
          if (viewResult.ViewBag.MasterPageViewModel != null) 
           return; 
    
          //setup model whichever way you want 
          var viewModel = new MasterPageViewModel(); 
          //inject model into ViewBag 
          viewResult.ViewBag.MasterPageViewModel = viewModel; 
         } 
    
         public void OnResultExecuted(ResultExecutedContext filterContext) 
         { 
         } 
        } 
    } 
    
  3. 配置過濾器供應商:

    //in Application_Start 
    FilterProviders.Providers.Add(new MasterPageViewModelInjectorFilterProvider()); 
    
  4. 使用在主:

    ViewBag.MasterPageViewModel 
    

這種方式,你有細解耦架構。當然,您可以將它與依賴注入結合使用(我們可以,但爲了清晰起見,我將其保留),並根據需要爲每個動作配置動作過濾器。

+0

適用於pro/elegant解決方案。 – devundef 2012-07-31 12:34:38

+0

偉大的解決方案。非常感謝。 – qinking126 2012-07-31 21:12:22

0

在這種情況下,您可以使用ViewBag。

public ActionResult Index(UserData userData) 
{ 
    AccountLoginWidgetVM model = new AccountLoginWidgetVM(); 
    if (null != userData) 
     model.UserData = userData; 

    ViewBag.UserData = userData; 
    return View(userData); 
} 


@Html.RenderPartial("LoginPartial", ViewBag.UserData) 

您必須確保userData不爲空。如果它將爲空,則傳遞的模型將成爲視圖的默認模型。