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

时间:2014-07-26 09:46:18

标签: c# asp.net-mvc

我创建了自己的控制器,如果Session存在执行操作,我会检查每个请求,否则重定向用户登录。

这是我的代码:

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();    
    }
}

当我转到主页/索引时,它会根据逻辑将我重定向到lo-gin,但如果已经登录(会话存在),则会抛出异常而不是执行该操作。< / p>

以下是例外:

  

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

2 个答案:

答案 0 :(得分:2)

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

我从未见过需要手动拨打Execute。不要这样做。将OnActionExecuting视为一个事件。您会收到某些事件的通知,可以挂钩,但不应该修改框架的行为方式。

答案 1 :(得分:0)

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

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());
}

实际上,此作业已有内置过滤器:http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute(v=vs.118).aspx

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new AuthorizeAttribute());
}