为什么 HTML.Action 会导致 Home/Index 方法仅在用户未通过身份验证时重复调用?

Why would an HTML.Action cause the Home/Index method to be called repeatedly only when user is not authenticated?

在_Layout.cshtml中,我使用以下调用:

@Html.Action("GetCurrentAnnouncement", "Announcement", new { isUserLoggedIn = User.Identity.IsAuthenticated })

它调用这个方法:

public async Task<PartialViewResult> GetCurrentAnnouncement(bool isUserLoggedIn)
    {
        var announcement = await _announcementService.GetCurrentAnnouncement(isUserLoggedIn);

        if (announcement == null) return null;

        var model = new AnnouncementDisplayViewModel();
        model.AnnouncementId = announcement.AnnouncementId;
        model.AnnouncementText = announcement.AnnouncementText;
        model.DisplayToAll = announcement.DisplayToAll;
        model.HyperText = announcement.HyperText;
        model.Url = announcement.Url;
        model.StartDate = announcement.StartDate;
        model.EndDate = announcement.EndDate;

        return PartialView("~/Views/Shared/_Announcement.cshtml", model);
    }

这在用户已经通过身份验证时工作得很好。 HomeController 的 Index 方法只被调用一次,我可以进入 GetCurrentAnnouncement 方法并观察它完美地完成它的工作,_Announcement.cshtml 显示得很好。

_Announcement.cshtml:

@model Announcement.AnnouncementDisplayViewModel
@{
    Layout = null;
}
<div class="row">
    <div class="col-md-12 announcement">
        <span class="full-announcement-text">@(Html.DisplayFor(m => m.AnnouncementText))</span>
        @if (Model.HyperText != "" && Model.HyperText != null)
        {
            <br />
            <a href="@Model.Url" target="_blank" class="announcement-link">@Model.HyperText</a>
        }
    </div>
</div>

问题是,如果我注销,Home/Index 方法会被重复调用,直到 Chrome 简短地警告我重定向太多,然后我收到 HTTP 错误 404.15 - 未找到 请求过滤模块用于拒绝查询字符串过长的请求。带有一个看起来很可笑的查询字符串 http://localhost:54578/?ReturnUrl=%2F%3FReturnUrl%3D%252F%253FReturnUrl%253D%25252F%25253FReturnUrl%25253D%2525252F%2525253FReturnUrl%2525253D%252525252F%252525253FReturnUrl%252525253D%25252525252F%25252525253FReturnUrl%25252525253D%2525252525252F%2525252525253FReturnUrl%2525252525253D%252525252525252F%252525252525253FReturnUrl%.....

在那种情况下,我一次也没有点击 GetCurrentAnnouncement 方法。只是 Home/Index 一遍又一遍,直到它厌倦了。我一辈子都弄不明白会发生什么。如果我将 GetCurrentAnnouncement 方法设置为非异步方法并将 return 设置为静态视图模型,没有传递给它的 isUserLoggedIn 参数,或者我尝试过的任何其他方法,都没有关系。这是 HomeController 的 Index 方法。它总是到达最后一行 return 主页视图(一遍又一遍):

        public ActionResult Index()
    {
        //Healt check to see if we have connection to the APIs and the DB
        var healtCheck = _heartbeatService.GetHeartBeat();

        if (healtCheck == null || healtCheck.Result == null || (!healtCheck.Result.Success))
        {
            return View("Error");
        }

        var user = System.Web.HttpContext.Current.User;

        bool userAuthenticated = (user != null) && user.Identity.IsAuthenticated;

        if (userAuthenticated)
        {
            if (user.IsInRole(Roles.WebAdmin) || user.IsInRole(Roles.Maintenance))
            {
                return RedirectToAction("Index", "Shop");

            }
            if (user.IsInRole(Roles.Shop))
            {
                return RedirectToAction("Index", "Referral");
            }
        }

        var viewModel = new LoginViewModel();
        return View("HomePage", viewModel);
    }

我确实在主页视图中发现了这一行有点有趣,但是表单从未提交,每次我点击它时,ViewBag.ReturnUrl 都是空的,所以 IDK:

@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))

找到了!我应该发布整个 AnnnouncementController;它在顶层有一个 [Authorize] 属性。通过在 GetCurrentAnnouncement 方法(无论用户是否登录都需要调用)上使用 [OverrideAuthorization] 属性,它解决了我所有的头痛问题。感谢所有线索,MVC。越了解你越不喜欢你,本来就不喜欢你。