Я недавно столкнулся с приведенным ниже кодом для перенаправления в случае ошибок в устаревшем приложении, сделанном с ASP. NET Core MVC:
app.UseStatusCodePages(async context => {
var response = context.HttpContext.Response;
if (response.StatusCode == (int)HttpStatusCode.Unauthorized ||
response.StatusCode == (int)HttpStatusCode.NotFound ||
response.StatusCode == (int)HttpStatusCode.Forbidden)
response.Redirect("/Account/Login");
});
Действие находится в AccountController.cs
ниже:
[Authorize]
public class AccountController : BaseController
{
public AccountController(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager,
ILogger<AccountController> logger,
DbContext dbContext)
: base(userManager, signInManager, logger, dbContext)
{
}
// GET: /Account/Login
[HttpGet]
[AllowAnonymous]
public async Task<ActionResult> Login(string returnUrl = null)
{
if (User.Identity.IsAuthenticated)
{
var user = await UserManager.FindByNameAsync(User.Identity.Name);
return await UserManager.IsInRoleAsync(user, "Admin") ||
await UserManager.IsInRoleAsync(user, "Sales")
? RedirectToAction("Index", "Companies", new {Area = "Sales"})
: RedirectToAction("Index", "Documents", new {Area = "Company", id = user.CompanyId});
}
return View();
}
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[AutoValidateAntiforgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
var result = await SignInManager.PasswordSignInAsync(
model.Email,
model.Password,
model.RememberMe,
true);
if (result.Succeeded)
{
var user = await UserManager.FindByEmailAsync(model.Email);
return await UserManager.IsInRoleAsync(user, "Admin") ||
await UserManager.IsInRoleAsync(user, "Sales")
? RedirectToAction("Index", "Companies", new {Area = "Sales"})
: RedirectToAction("Index", "Documents", new {Area = "Company", id = user.CompanyId});
}
if (result.IsLockedOut)
{
return View("Lockout");
}
if (!result.IsNotAllowed)
{
ModelState.AddModelError(string.Empty, Resource.InvalidLoginAttempt);
}
return View(model);
}
// ...
}
_ViewStart.cshtml
:
@{
Layout = "_mainLayout";
}
Login.cshtml
:
@using MySecretProject.Core.App_LocalResources
@using Microsoft.AspNetCore.Mvc.Rendering
@model MySecretProject.Core.Models.Account.LoginViewModel
@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer
@{
ViewBag.Title = MySecretProject.Core.App_LocalResources.Views.Account.Login.Account_Login_Title;
}
@using (Html.BeginForm("Login", "Account", new { ViewBag.ReturnUrl }, FormMethod.Post, true, new { role = "form", @class = "form-horizontal contentPane2 contentPane2TopMargin" }))
{
@Html.AntiForgeryToken()
<div class="tab" style="width: 100%">
<div id="TopHeader" class="documentTabHeaderTop"> </div>
<div class="container-fluid documentTitleHeader text-center documentTabHeaderTd-active">
<div>Sign in</div>
<div class="col-xs-12 col-sm-12 col-lg-12 headImage">@Html.ValidationSummary(true)</div>
</div>
</div>
<div class="form-group has-feedback">
<div class="col-lg-10 col-md-10 col-sm-10 col-xs-10 col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-envelope"></i></span>
@Html.TextBoxFor(m => m.Email, new {@class = "form-control", @placeholder = "Email", aria_describedby = "EMailStatus"})
@Html.ValidationMessageFor(m => m.Email, null, new { @class = "sr-only", id = "EMailStatus" })
</div>
</div>
</div>
<div class="form-group has-feedback">
<div class="col-lg-10 col-md-10 col-sm-10 col-xs-10 col-lg-offset-1 col-md-offset-1 col-sm-offset-1 col-xs-offset-1">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
@Html.PasswordFor(m => m.Password, new {@class = "form-control", @placeholder = Resource.Password, aria_describedby = "PasswordBlock"})
@Html.ValidationMessageFor(m => m.Password, null, new {@class = "sr-only", id = "PasswordBlock"})
</div>
</div>
</div>
<div class="form-group">
<div class="text-center">
<div>
<input type="submit" id="ContinueButton" value="@Resource.Continue.ToUpper()" class="buttonItem buttonItem-valid"/>
</div>
</div>
</div>
<div class="form-group">
</div>
<div class="form-group">
<div class="text-center">
@Html.ActionLink(Resource.PasswordForgotten, "ForgotPassword", "Account", string.Empty, new { @style = "text-decoration: none;"})
</div>
</div>
}
Перенаправление ведет к представлению входа в систему, но вместо того, чтобы иметь Login.cshtml
в _mainLayout.cshtml
только один раз. Это происходит дважды.
Как этого избежать?
![enter image description here](https://i.stack.imgur.com/IJfSE.png)
[EDIT]
Чтобы дать суть что происходит:
![enter image description here](https://i.stack.imgur.com/NZU5P.png)