RedirectToAction, RedirectToRoute и RedirectToLocal приводят к зависанию приложения периодически - PullRequest
0 голосов
/ 25 апреля 2019

Это проблема, с которой я сталкиваюсь уже несколько недель.Похоже, что это происходит на моем входе в систему в контроллере учетной записи.Кажется, что это также зависит от машины, с которой я работаю для просмотра сайта, поскольку я сталкиваюсь с проблемой только на моей домашней машине, а не на моей рабочей машине.Я знаю, что это не зависит от браузера, так как оба используют одну и ту же версию Chrome.Он также не изолирован ни от одной среды, поскольку я получу его отладку локально и просмотр самого сайта.

Сначала я подумал, что это как-то связано с тем, что я использую метод Async, как и я.не так хорошо знаком с их использованием, как я с синхронными методами.Я пытался раздеть все и сделать действие, а также все в нем полностью синхронным и все еще получал тот же результат.Затем я попытался заменить redirecttoaction / route / locals на простой возврат представления, и это сработало.Для дальнейшего подтверждения того, что виновник был, моя форма входа в систему попала в совершенно другое действие, которое было ДРУГОЙ, чем простое действие перенаправления («Индекс», «Домой»), и приложение просто зависло на неопределенное время.К сожалению, простое нажатие на вид не работает для моих нужд, так как во многих случаях оно мне нужно для самого действия.

С точки зрения его непоследовательности, единственный способ, которым я смог последовательно воспроизвести его, - этоЗапустите приложение локально и войдите в систему. Затем я закрою браузер и перестану запускать приложение.Затем я снова запускаю приложение> выйти> войти, и оно зависает.

Я провел здесь большое количество исследований на stackoverflow и других сайтах и ​​испробовал множество различных рекомендаций, таких как изменение настроек конфигурации вstartup.cs, переустановка dll и слишком много других вещей, чтобы сосчитать, и мне просто не повезло, решая это.

Вот конструктор и вход в систему get и post из контроллера учетной записи

private myContext _context;
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
private readonly RoleManager<IdentityRole> _roleManager;
private readonly IEmailSender _emailSender;
private readonly ISmsSender _smsSender;
private readonly ILogger _logger;

public AccountController(
    myContext context,
    UserManager<ApplicationUser> userManager,
    SignInManager<ApplicationUser> signInManager,
    RoleManager<IdentityRole> roleManager,
    IEmailSender emailSender,
    ISmsSender smsSender,
    ILoggerFactory loggerFactory)
{
    _context = context;
    _userManager = userManager;
    _signInManager = signInManager;
    _roleManager = roleManager;
    _emailSender = emailSender;
    _smsSender = smsSender;
    _logger = loggerFactory.CreateLogger<AccountController>();
}


// GET: /Account/Login
[HttpGet]
[AllowAnonymous]
public IActionResult Login(string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    return View();
}

// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        ApplicationUser user = _userManager.Users.Where(a => a.Email == model.Email).FirstOrDefault();

        if (user != null)
        {
            var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: true);
            if (result.Succeeded)
            {

                _logger.LogInformation(1, "User logged in.");
                var RoleCustomer = _userManager.IsInRoleAsync(user, "Customer");
                var RoleAdmin = _userManager.IsInRoleAsync(user, "Admin");
                if (RoleCustomer.Result)
                {
                    return RedirectToLocal(returnUrl);
                }
                else if (RoleAdmin.Result)
                {

                    return RedirectToRoute(new { controller = "Home", action = "Admin" });
                    //return RedirectToLocal("/Home/Index");
                }
                else
                {
                    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                    return View(model);
                }

            }
            if (user.EmailConfirmed == false)
            {
                return View("ResendConfirm", new ResendConfirmViewModel() { user = user, returnUrl = returnUrl });
            }

            if (result.IsLockedOut)
            {
                _logger.LogWarning(2, "User account locked out.");
                return View("Lockout");
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                return View(model);
            }
        }
        else
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return View(model);
        }


    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

Вот форма входа в систему из вида входа в систему

<form asp-controller="Account" asp-action="Login" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal" role="form">
    <h4>Use a local account to log in.</h4>
    <hr />
    <div asp-validation-summary="All" class="text-danger"></div>
    <div class="form-group">
        <label asp-for="Email" class="col-md-2 control-label"></label>
        <div class="col-md-10">
            <input asp-for="Email" class="form-control" />
            <span asp-validation-for="Email" class="text-danger"></span>
        </div>
    </div>
    <div class="form-group">
        <label asp-for="Password" class="col-md-2 control-label"></label>
        <div class="col-md-10">
            <input asp-for="Password" class="form-control" />
            <span asp-validation-for="Password" class="text-danger"></span>
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <div class="checkbox">
                <label asp-for="RememberMe">
                    <input asp-for="RememberMe" />
                    @Html.DisplayNameFor(m => m.RememberMe)
                </label>
            </div>
        </div>
    </div>
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <button type="submit" class="btn btn-default">Log in</button>
        </div>
    </div>
    <p>
        <a asp-action="Register" asp-route-returnurl="@ViewData["ReturnUrl"]">Register as a new user?</a>
    </p>
    <p>
        <a asp-action="ForgotPassword">Forgot your password?</a>
    </p>
</form>

Вот класс запуска

public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services.AddDbContext<myContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("WebApplication1ContextConnection")));

            services.AddIdentityCore<ApplicationUser>()
                .AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<myContext>()
                .AddSignInManager()
                .AddDefaultTokenProviders();

            services.AddAuthentication(o =>
            {
                o.DefaultScheme = IdentityConstants.ApplicationScheme;
                o.DefaultSignInScheme = IdentityConstants.ExternalScheme;
            })
            .AddIdentityCookies(o => { });

            services.AddSession();

            services.Configure<IdentityOptions>(options =>
            {
                // Default Lockout settings.
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
                options.Lockout.MaxFailedAccessAttempts = 5;
                options.Lockout.AllowedForNewUsers = true;
                options.Password.RequireDigit = true;
                options.Password.RequireLowercase = true;
                options.Password.RequireNonAlphanumeric = true;
                options.Password.RequireUppercase = true;
                options.Password.RequiredLength = 6;
                options.Password.RequiredUniqueChars = 1;
                options.SignIn.RequireConfirmedEmail = true;
                options.SignIn.RequireConfirmedPhoneNumber = false;
                options.User.AllowedUserNameCharacters ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
                options.User.RequireUniqueEmail = true;
            });

            services.ConfigureApplicationCookie(options =>
            {
                //should change this at some point to real access denied. something like Account/AccessDenied
                options.AccessDeniedPath = "/Home/index";
                options.Cookie.Name = "mycookie";
                options.Cookie.HttpOnly = true;
                options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
                options.LoginPath = "/Account/Login";
                // ReturnUrlParameter requires 
                //using Microsoft.AspNetCore.Authentication.Cookies;
                options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
                options.SlidingExpiration = true;
            });

            services.Configure<PasswordHasherOptions>(option =>
            {
                option.IterationCount = 12000;
            });



            // Add application services.
            services.AddTransient<IEmailSender, AuthMessageSender>();
            services.AddTransient<ISmsSender, AuthMessageSender>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();

            app.UseSession();

            app.UseStaticFiles();

            app.UseCookiePolicy();

            app.UseAuthentication();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }

Заранее большое спасибо за любую помощь /руководство, которое вы можете предоставить.Я очень ценю это.Если я могу предоставить больше информации, пожалуйста, дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...