在 MVC3 中覆盖 RenderBody 内容而不重定向用户

发布于 2025-01-08 07:52:39 字数 1022 浏览 2 评论 0原文

我试图这样做:

<body>
    <div id="Page">
        <div id="TopBar">
            <div id="TopBarLogo">
                <img src="@Url.Content("~/Content/images/Weblogo.png")" />
            </div>
            <div>
                @{ Html.RenderAction("MenuPartial", "MenuPartial"); }
            </div>
        </div>
        <div class="Content">
            @if (SessionWrapper.IsAuthenticated)
            {
                @RenderBody()
            }
            else
            {
                Html.RenderPartial("AccessDeniedPartial");
            }
        </div>
    </div>
</body>
</html>

但是 ofc 这是不允许的,因为我需要 @RenderBody() 否则会发生异常。 问题是这个解决方案会非常简洁,我仍然想渲染页面的顶部,但我想覆盖内容,除非用户登录。

我能想到的唯一其他解决方案是执行签入控制器并返回另一个视图。问题是我必须在每个控制器中重复这段代码,这让我很难过。

有没有办法全局覆盖与上面类似的内容,而不将用户重定向到另一个网址?如果有的话,请您给我一个正确的方向。我似乎有点陷入目前的心态。

我没有使用默认的 Microsoft 安全类 (FormsAuthentication),在这种情况下我也无法使用。

谢谢。

I was trying to do this:

<body>
    <div id="Page">
        <div id="TopBar">
            <div id="TopBarLogo">
                <img src="@Url.Content("~/Content/images/Weblogo.png")" />
            </div>
            <div>
                @{ Html.RenderAction("MenuPartial", "MenuPartial"); }
            </div>
        </div>
        <div class="Content">
            @if (SessionWrapper.IsAuthenticated)
            {
                @RenderBody()
            }
            else
            {
                Html.RenderPartial("AccessDeniedPartial");
            }
        </div>
    </div>
</body>
</html>

But ofc this is not allowed, as I need to have @RenderBody() or an exception occurs.
The problem is that this solution would have been so neat, I still want to render the top part of the page, but I would like to override the content unless user is logged in.

The only other solution I can think of is to do the check in the controller and return another view. The problem with that is that I would have to repeat this code in every controller which makes me sad.

Is there any way to globally override the content similar to above, without redirecting the user to another url? If there is, could you please give me a nudge in the right direction. I seem to be a bit stuck in my current mindset.

Im not using the default Microsoft security classes (FormsAuthentication), nor am I able to in this case.

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深陷 2025-01-15 07:52:39

在 Views/Shared 文件夹中创建一个与 AccessDeniedPartial 内容相同的 AccessDenied 视图。
保持 RenderBody 不变:

<div class="Content">
    @RenderBody()
</div>

创建一个 LogOnAuthorizeAttribute 来检查身份验证,否则显示 AccessDenied 视图。

public class LogOnAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (!SessionWrapper.IsAuthenticated)
        {
            filterContext.Result = new ViewResult {ViewName = "AccessDenied"};
        }
        else
        {
            base.OnAuthorization(filterContext);
        }
    }
}

如果您希望将 LogOnAuthorizeAttribute 添加到每个控制器,请将其作为过滤器添加到 Global.asax 中的 GlobalFilterCollection 中。

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new LogOnAuthorizeAttribute());
}

Create an AccessDenied view in the Views/Shared folder that has the same content as your AccessDeniedPartial.
Leave the RenderBody as it is:

<div class="Content">
    @RenderBody()
</div>

Create an LogOnAuthorizeAttribute that will check for authentication, otherwise show the AccessDenied view.

public class LogOnAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (!SessionWrapper.IsAuthenticated)
        {
            filterContext.Result = new ViewResult {ViewName = "AccessDenied"};
        }
        else
        {
            base.OnAuthorization(filterContext);
        }
    }
}

If you want the LogOnAuthorizeAttribute to be added to each controller, add it as a filter to the GlobalFilterCollection in Global.asax.

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new LogOnAuthorizeAttribute());
}
甜是你 2025-01-15 07:52:39

我能想到的唯一其他解决方案是在控制器中进行检查并返回另一个视图。

是的,这样做

问题是我必须在每个控制器中重复这段代码,这让我很难过。

好吧,不,如果您使用新的 mvc 面向方面编程模型,它基于过滤器属性。检查AuthorizeAttribute和asp.net mvc的过滤器模型。

[Authorize]
public ViewResult MyAction(...)

您可以非常轻松地自定义此 Authorize 属性的行为。

您还可以在这里阅读有关面向方面编程的更多信息:
http://en.wikipedia.org/wiki/Aspect-oriented_programming

The only other solution I can think of is to do the check in the controller and return another view.

yes do that

The problem with that is that I would have to repeat this code in every controller which makes me sad.

well no, if you use the new aspect-oriented programming model of mvc, which is based on filter attributes. Check the AuthorizeAttribute and the filter model of asp.net mvc.

[Authorize]
public ViewResult MyAction(...)

You can customize the behavior of this Authorize attribute quite easily.

Also you can read more about aspect oriented programming here:
http://en.wikipedia.org/wiki/Aspect-oriented_programming

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文