我有一个名为LockScreen的类来阻止应用程序。 在阻止屏幕,重新加载页面或通过地址输入页面后,我收到错误,因为我总是进入LockScreen类,然后我得到一个循环。
我该如何解决?我需要始终重定向到LockScreen视图,但我不想要循环。
LockScreen类:
namespace ApplicaAccWeb.Validators
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class LockScreenAttribute : ActionFilterAttribute, IActionFilter
{
public static int countLockScreen;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
try
{
var lockScreen = filterContext.HttpContext.Session["lockScreen"];
if ((string)lockScreen == "Lock")
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(
new { controller = "Account", action = "LockScreen" }));
}
}
catch (Exception)
{
}
}
}
}
}
的AccountController:
[Authorize]
[LockScreen]
public class AccountController : Controller
{
}
操作GET LockScreen:
public ActionResult LockScreen()
{
ViewBag.Username = User.Identity.GetUserName();
this.Session.Add("lockScreen", "Lock");
return View();
}
动作POST LockScreen:
/// <summary>
/// Permite desbloquear la sesión de un usuario.
/// </summary>
[LogActionFilter]
[HttpPost]
public async Task<ActionResult> LockScreen(string UserName, string Password)
{
if (!String.IsNullOrEmpty(UserName) && !String.IsNullOrEmpty(Password))
{
// No cuenta los errores de inicio de sesión para el bloqueo de la cuenta
// Para permitir que los errores de contraseña desencadenen el bloqueo de la cuenta, cambie a shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(UserName, Password, false, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
this.Session.Add("lockScreen", "UnLock");
LockScreenAttribute.countLockScreen = 0;
return Json(new Dictionary<string, string>() { { "success", "Unlock satisfactorio." } });
case SignInStatus.LockedOut:
return Json(new Dictionary<string, string>() { { "error", "Usuario bloqueado." } });
case SignInStatus.RequiresVerification:
//return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Contraseña inválida.");
return Json(new Dictionary<string, string>() { { "error", "Contraseña inválida." } });
}
}
else
{
ViewBag.Username = User.Identity.GetUserName();
return View();
}
}
FilterConfig类:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
// filters.Add(new LogActionFilter());
}
}
答案 0 :(得分:1)
您尚未将[LockScreen]
属性注册为全局操作过滤器,这是正确的做法,但您已在AccountController
上使用它。这意味着每次调用Account控制器的任何操作时都会执行[LockScreen]
操作过滤器,包括LockScreen
操作。因此,当您重定向到LockScreen
操作过滤器中的[LockScreen]
操作时,会在调用[LockScreen]
操作之前再次调用LockScreen
操作过滤器;这会导致递归循环。为避免这种情况,请在操作级别定义操作筛选器,并仅针对需要它的操作,而不是在控制器级别。因此,您的帐户控制器应如下所示:
[Authorize]
// Remove the [LockScreen] attribute
public class AccountController : Controller
{
}
相反,将[LockScreen]
属性添加到控制器中的所有操作,LockScreen
操作除外。
答案 1 :(得分:0)
更新:解决方案
创建一个被调用的类:
public class SkipImportantTaskAttribute : Attribute
{
}
将条件添加到我的FilterAction&#34; LockScreenAttribute&#34;:
namespace ApplicaAccWeb.Validators
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)]
public class LockScreenAttribute : ActionFilterAttribute, IActionFilter
{
public static int countLockScreen;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
/// This is a new Code--------------------------------
bool skipImportantTaskFilter = filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(SkipImportantTaskAttribute), true) ||
filterContext.ActionDescriptor.IsDefined(typeof(SkipImportantTaskAttribute), true);
if (!skipImportantTaskFilter)
{
PerformModelAlteration(filterContext);
}
}
////----------------------------------------------
}
////Only entering here if Bool is true------------------------
private void PerformModelAlteration(ActionExecutingContext filterContext)
{
try
{
var lockScreen = filterContext.HttpContext.Session["lockScreen"];
if ((string)lockScreen == "Lock")
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(
new { controller = "Account", action = "LockScreen" }));
}
base.OnActionExecuting(filterContext);
}
catch (Exception)
{
}
}
}
}
接下来将[SkipImportantTaskAttribute]添加到我的操作需要忽略
[HttpPost]
[SkipImportantTask]
public async Task<ActionResult> LockScreen(string UserName, string Password)
{
<强> 重要 强> @ataravati的解决方案很棒。