C# 控制器的单个实例不能用于处理多个请求

C# 控制器的单个实例不能用于处理多个请求,c#,asp.net-mvc,C#,Asp.net Mvc,我已经创建了自己的控制器,在其中检查每个请求是否存在会话执行操作,否则重定向用户进行登录 这是我的密码: public class DefaultController : Controller { protected override void OnActionExecuting(ActionExecutingContext filterContext) { if (filterContext.HttpContext.Session["User"] == null

我已经创建了自己的控制器,在其中检查每个请求是否存在会话执行操作,否则重定向用户进行登录

这是我的密码:

public class DefaultController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.HttpContext.Session["User"] == null)
        {
            filterContext.Result = RedirectToAction("Login", "Account");
        }
        else
        {
            base.Execute(filterContext.RequestContext);
        }
    }
}
我正在控制器中使用它:

public class HomeController : DefaultController
{
    public ActionResult Index()
    {
        // DXCOMMENT: Pass a data model for GridView
        return View();    
    }
}
当我转到Home/Index时,它根据逻辑将我重定向到lo gin,但如果会话中已经存在use,它将抛出异常,而不是执行该操作

例外情况如下:

控制器的单个实例不能用于处理多个请求。如果正在使用自定义控制器工厂,请确保它为每个请求创建一个新的控制器实例


授权是一个贯穿各领域的问题。您应该将逻辑编写为过滤器

public class CustomAuthAttribute : FilterAttribute, IActionFilter { 

     public void OnActionExecuting(ActionExecutingContext filterContext) {
         if (filterContext.HttpContext.Session["User"] == null)
         {
            filterContext.Result = new RedirectToRouteResult(
                                      new RouteValueDictionary 
                                      {
                                         { "action", "Login" },
                                         { "controller", "Account" }
                                      }); 
         }
     } 
}
并将其注册为全局过滤器,以防您需要将逻辑应用于所有控制器

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new CustomAuthAttribute());
}
实际上,此作业已经有一个内置筛选器:

在OnActionExecution方法中,您正在执行当前请求:base.Execute。框架稍后会再次执行,因为它不知道您已经执行了


我从未见过需要手动调用Execute。不要那样做。将OnActionExecuting视为一个事件。您会收到一些事件的通知,可以挂接,但不应该修改框架的行为。

您可以使用async await在它自己的线程中执行每个操作。如果您有最新的VS和.NET,请尝试添加新的MVC/WebAPI项目,新的示例项目默认使用async/await。希望这有帮助。你应该将逻辑写在一个过滤器中。@KhanhTO在这种情况下,我必须为会话检查显式地修饰每个操作。我需要更通用的方法,所以我这样做。如果你需要将过滤器注册为全局的,你可以用一些示例来详细说明吗?覆盖内置的如何filter@EhsanSajjad:关于覆盖,已经有了stackoverflow的答案:@Ehsan Sajjad:我通常只使用内置过滤器,不做任何修改。但这样我就必须用它来装饰操作attribute@EhsanSajjad:通过将过滤器注册为全局过滤器,它将应用于所有控制器。你不需要手工装饰。
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new AuthorizeAttribute());
}