这是关于@Andre Calil在以下SO中提供的解决方案的问题 Razor MVC, where to put global variables that's accessible across master page, partiview and view?
我正在使用安德烈的方法,并有一个小问题: 我的_Layout强类型为BaseModel,我的视图强类型为AccountModel,它继承自BaseModel。
问题:如果我返回一个没有模型的视图,即返回View(),那么我会得到一个异常。这是因为BaseController OnActionExecuted事件正在检查提供的模型是否为null,如下所示:
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Result is ViewResultBase)//Gets ViewResult and PartialViewResult
{
object viewModel = ((ViewResultBase)filterContext.Result).Model;
if (viewModel != null && viewModel is MyBaseModel)
{
MyBaseModel myBase = viewModel as MyBaseModel;
myBase.Firstname = CurrentUser.Firstname; //available from base controller
}
}
base.OnActionExecuted(filterContext);//this is important!
}
模型为null,因此这种情况并不总是有效。我的下一步是确保我总是将模型传递给视图,即使它是一个空的BaseModel对象。问题是我得到以下异常:
The model item passed into the dictionary is of type 'MyNamespace.BaseModel', but this dictionary requires a model item of type 'MyNamespace.AccountModel'.
我需要澄清两点:
答案 0 :(得分:1)
您需要查看Phil Haacked在本文中描述的自定义剃刀视图:
http://haacked.com/archive/2011/02/21/changing-base-type-of-a-razor-view.aspx
所以基本上在你的BaseController中你要设置一个公共变量,它将在基本控制器的Initialize事件中的每个请求中获取(在我的例子中,它是User的实例):
public class BaseController : Controller
{
public User AppUser;
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
AppUser = _userService.GetUser(id);
ViewBag.User = AppUser;
}
}
所以现在你有一个变量可以被任何从基本控制器继承的控制器访问。剩下要做的唯一事情就是弄清楚如何在视图中使用这个变量。这是我上面链接的文章将帮助您。默认情况下,所有视图都是从System.Web.Mvc.WebViewPage生成的。但是,您可以通过执行以下操作来自定义此类的实现:
namespace YourApplication.Namespace
{
public abstract class CustomWebViewPage : WebViewPage
{
private User _appUser;
public User AppUser
{
get
{
try
{
_appUser = (User)ViewBag.User;
}
catch (Exception)
{
_appUser = null;
}
return _appUser;
}
}
}
public abstract class CustomWebViewPage<TModel> : WebViewPage<TModel> where TModel : class
{
private User _appUser;
public User AppUser
{
get
{
try
{
_appUser = (User)ViewBag.User;
}
catch (Exception)
{
_appUser = null;
}
return _appUser;
}
}
}
}
您刚刚定义了一个自定义剃刀视图类,它具有user的属性,并尝试从我们在基本控制器中设置的ViewBag.User中获取它。剩下要做的就是告诉你的应用在尝试生成视图时使用这个类。您可以通过在VIEWS web.config文件中设置以下行来执行此操作:
<pages pageBaseType="YourApplication.Namespace.CustomWebViewPage">
现在,在您的视图中,您可以获得您可以使用的用户属性的帮助:
@AppUser
请注意,页面声明需要进入VIEWS web.config文件而不是主应用程序web.config!
我认为这是一个更好的解决方案,因为您不必通过视图模型为所有视图提供基本模型。视图模型应该保留用于预期的目的。