引用NerdDinner ASP.NET MVC示例应用程序
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%
if (Request.IsAuthenticated) {
%>
Welcome <b><%= Html.Encode(Page.User.Identity.Name) %></b>!
[ <%= Html.ActionLink("Log Off", "LogOff", "Account") %> ]
<%
}
else {
%>
[ <%= Html.ActionLink("Log On", "LogOn", "Account") %> ]
<%
}
%>
这是来自名为LoginStatus.ascx的局部视图usercontrol。正如您所看到的,存在改变视图的“整个”输出的条件。这是正确的方法吗?如果有控制器评估这个条件然后渲染适当的局部视图会更好吗?
无论您对上一个问题的回答如何,我如何在ASP.NET MVC中采用后一种方法,即父视图可以调用控制器(而不是执行UserControl的RenderPartial)并让它决定哪个局部视图渲染?
答案 0 :(得分:4)
这种方法怎么样:
解决方案1 :
在HtmlHelper
上创建一个扩展方法,该方法将根据请求呈现“WelcomeMessage.Anonymous.aspx”或“WelcomeMessage.Authenticated.aspx”视图。
<%= Html.LoginStatus() =>
并将这些观点放在/ Views / Shared
下/Views/Shared/LoginStatus.Anonymous.ascx
/Views/Shared/LoginStatus.Authenticated.ascx
解决方案2 :
在LoginStatus.ascx中用ASP.NET LoginView控件替换if / else
语句
<asp:LoginView Runat="Server">
<LoggiedInTemplate>
Welcome, <%= Html.Encode(Model.UserName) %>!
<button>Sign Out</button>
</LoggedInTemplate>
<AnonymousTemplate>
<button>Sign In</button> | <button>Join Now!</button>
</AnonymousTemplate>
</asp:LoginView>
另见:
答案 1 :(得分:1)
我认为如果视图会根据某些条件进行相应更改,那么视图的责任就是强制执行此操作。但是如果条件正在改变而不是外观(即“负数应该是红色”)但是行为(即“如果用户登录s /他必须看到LOGOUT按钮而不是LOGIN按钮”)那么它的控制器来决定。您可能会在控制器和页面之间引入“渲染器”级别。
答案 2 :(得分:0)
我认为你在做的事情很好。诸如展示变化之类的小事可以而且应该由观点来进行。
例如,我有一个由单独的ascx渲染的主菜单。内部有很多这样的小检查,以决定要显示的文本以及应用于列表元素的样式。
如果有很大的决定,比如根据某些用户操作考虑要渲染的视图,那么控制器会对业务逻辑提出质疑,并决定返回重定向位置的视图。但如果它是一个非常稳定的UI元素,其中只有文本和颜色选项略有改变,那么将必要的逻辑放入其中。
您还可以将单独的模型传递给ascx,并使用几个标志来定义应显示的内容和方式。然后,设置这些标志的实际逻辑将位于业务逻辑级别的其他位置,您的所有视图都将只是查看这些标志并进行相应的渲染。
别担心,你做得对。
答案 3 :(得分:0)
您可以在控制器中执行此操作,而不是决定用户是否在视图中进行了身份验证,如下所示:
public ActionResult ShowAPage()
{
if(!HttpContext.User.Identity.IsAuthenticated)
{
return RedirectToRoute("ShowLoginPage")
}
return View();
}
然后你可以重定向到一个登录页面而不是在视图中使用这个逻辑,这实际上不是关注点的分离。
这样做非常酷的方法是为经过身份验证的用户使用与未经过身份验证的用户不同的母版页。我认为你想要始终显示登录或注销链接,这样你就可以使用ActionFilter根据用户的身份验证来更改母版页。然后,您登录的用户可以获得您可能希望隐藏在外部人员之类的导航栏,而无需在显示逻辑中对此进行判断。
这是在不使用动作过滤器的情况下执行此操作的一种方法,但您可以采用各种方式,一种方法是创建从控制器继承的自定义控制器,并覆盖View方法以选择适当的母版页。< / p>
public ActionResult ShowAPage()
{
if(!HttpContext.User.Identity.IsAuthenticated)
{
return View("ShowAPageView", "LoggedInMasterPageName");
}
return View("ShowAPageView", "LoggedOutMasterPageName");
}
希望这有帮助。