Как передать значение на главную страницу MVC3 (макет)?
У меня есть пользовательский modelbinder, его проверка подлинности 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 ответа:
Мы сделали это следующим образом:
Определен отдельный viewmodel для мастер-страниц.
public class MasterPageViewModel { public Guid CurrentUserId { get; set; } public string CurrentUserFullName { get; set; } }
Добавлены инжекционный фильтр и поставщик фильтров.
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) { } } }
Настройка поставщика фильтров:
//in Application_Start FilterProviders.Providers.Add(new MasterPageViewModelInjectorFilterProvider());
Использование в master:
ViewBag.MasterPageViewModel
Таким образом, Вы имеете прекрасную несвязанную архитектуру. Конечно, вы можете объединить его с инъекцией зависимостей (мы это делаем, но я оставил его для ясности) и настроить фильтр действий для каждого действия какой бы путь вы хотите.
В этом случае вы можете использовать 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, то переданная модель будет моделью представления по умолчанию.