I have a custom modelbinder, its check the authentication cookie and return the value.
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;
}
}
if I need to use it, I just need to pass it to the action. everything works.
public ActionResult Index(UserData userData)
{
AccountLoginWidgetVM model = new AccountLoginWidgetVM();
if (null != userData)
model.UserData = userData;
return View(userData);
}
However, I want to use it in my master page, because once user login, i want to display their info on the top on every page. I tried a few things, coudln't get it work
@Html.RenderPartial("LoginPartial", ???model here??)
We did it as follows:
Defined separate viewmodel for masterpages.
public class MasterPageViewModel { public Guid CurrentUserId { get; set; } public string CurrentUserFullName { get; set; } }
Added injection filter and filter provider.
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) { } } }
Configure filter provider:
//in Application_Start FilterProviders.Providers.Add(new MasterPageViewModelInjectorFilterProvider());
Use in master:
ViewBag.MasterPageViewModel
This way you have fine uncoupled architecture. Of course you can combine it with Dependency Injection (we do, but I left it out for clarity) and configure your action filter for every action whichever way you want.
In this case you can use 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)
You have to make sure that userData is not null. If it'll be null the passed model will be default model of the view.
来源:https://stackoverflow.com/questions/11739905/how-do-i-pass-value-to-mvc3-master-page-layout