如何将值传递给MVC3母版页(_layout)?

时间:2012-07-31 12:18:46

标签: asp.net-mvc asp.net-mvc-3 model-binding

我有一个自定义模型绑定器,它检查身份验证cookie并返回值。

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

但是,我想在我的母版页中使用它,因为一旦用户登录,我想在每个页面的顶部显示他们的信息。我尝试了一些事情,但没有得到它的工作

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

2 个答案:

答案 0 :(得分:11)

我们这样做了:

  1. 为主页定义了单独的viewmodel。

    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. 在master中使用:

    ViewBag.MasterPageViewModel
    
  5. 这样你就可以得到很好的解耦结构。当然,您可以将它与依赖注入相结合(我们这样做,但为了清晰起见,我将其删除)并为您希望的每种操作配置动作过滤器。

答案 1 :(得分: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不为null。如果它为null,则传递的模型将是视图的默认模型。