【问题标题】:ASP.NET MVC: Action Filter to set up controller variables?ASP.NET MVC:设置控制器变量的操作过滤器?
【发布时间】:2011-07-13 13:32:14
【问题描述】:

我有一个场景,对于每个页面请求,我都必须检查会话是否存在特定 ID。如果找到了,我必须从数据库中获取一个相关的对象,并将其提供给控制器。如果找不到会话 ID,我需要重定向用户(会话已过期)。

目前,我有一段自定义代码(几行)在我的控制器中的每个操作方法的开头执行此操作 - 这似乎是不必要的重复。

这个场景值得一个动作过滤器吗?

谢谢

更新 伙计们,这里有一些很棒的信息。谢谢

【问题讨论】:

    标签: asp.net asp.net-mvc action-filter


    【解决方案1】:

    是的,这听起来像是动作过滤器的一个很好的应用,因为您可以在控制器级别应用它来操作所有动作。如果您不想手动将其添加到所有控制器,也可以将其作为控制器基类的一部分,或者编写自己的控制器工厂,自动将此操作过滤器应用于每个控制器。

    请参阅ASP.NET MVC Pass object from Custom Action Filter to Action,了解将数据从操作过滤器传递到操作。

    【讨论】:

    • +1 并感谢您提供第二段中的链接 - 让我找到了解决类似问题所需的内容。
    【解决方案2】:

    像这样创建一个基本控制器

       public class MyContollerController : Controller
        {
            public DataEntity userData;
            protected override void Initialize(System.Web.Routing.RequestContext requestContext)
            {            
                base.Initialize(requestContext);
                var customId = requestContext.HttpContext.Session["key"];
                if(customId!=null)
                {
                     userData=getDataGromDataBase(customId);
                }   
                else
                {
                   //redirect User
                }     
            }
        }
    

    现在像这样创建你的控制器

    public class MyDemoController : MyContollerController
    {
            public ActionResult Action1()
            { 
                 //access your data
                 this.userData
    
            }
            public ActionResult Action2()
            { 
                 //access your data
                 this.userData
    
            }
    }
    

    【讨论】:

    • 我已经使用 MVC 快四年了,从来不知道 Initialize 方法,所以谢谢!我一直将这种逻辑推入我的基本控制器的OnActionExecuting 方法中,但现在我看到Initialize 似乎更……理想。这是因为我们都应该知道,构造函数使我们失败,因为并非所有控制器属性在调用时都已完全准备好。对于懒惰的人,Initialize 上的 Intellisense 表示“初始化在调用构造函数时可能不可用的数据”。再次感谢您!
    【解决方案3】:

    另一种方法是使用模型绑定器来做到这一点。假设该对象是 ShoppingCart

    //Custom Model Binder
    public class ShoppingCarModelBinder : IModelBinder
        {
            public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            {
                //TODO: retrieve model or return null;
            }
        }
     //register that binder in global.asax in application start
    
    ModelBinders.Binders.Add(typeof(ShoppingCart), new ShoppingCartBinder());
    
    // controller action
    
    public ActionResult DoStuff(ShoppingCart cart)
    {
         if(cart == null)
         {
         //whatever you do when cart is null, redirect. etc
         }
         else
         {
         // do stuff with cart
         }
    }
    

    此外,这是一种更易于单元测试且更清晰的方式,因为这种方式的操作依赖于从外部提供的参数

    【讨论】:

      猜你喜欢
      • 2010-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-23
      • 1970-01-01
      • 2012-07-06
      • 2016-06-27
      • 1970-01-01
      相关资源
      最近更新 更多