我有一个场景,每个页面请求都必须检查会话中是否存在特定ID。如果找到这个,我必须从数据库中获取一个相关对象,并使其可供控制器使用。如果找不到会话ID,我需要重定向用户(会话已过期)。
目前我有一个自定义的代码块(几行)在我的控制器中的每个动作方法的开头都这样做 - 这似乎是不必要的重复。
这种情况是否值得采取行动过滤器?
由于
UPDATE 这里有一些很棒的信息。谢谢
答案 0 :(得分:9)
是的,这听起来像是一个很好的动作过滤器应用程序,因为您可以在控制器级别应用它来操作所有操作。如果您不想手动将其添加到所有控制器,也可以将其作为控制器基类的一部分,或者编写自己的控制器工厂,自动将此操作过滤器应用于每个控制器。
有关将动作过滤器中的数据传递给操作的信息,请参阅ASP.NET MVC Pass object from Custom Action Filter to Action。
答案 1 :(得分:9)
像这样创建一个基本控制器
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
}
}
答案 2 :(得分:3)
另一种方法是使用Model Binders。假设该对象是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
}
}
此外,这是更加单元可测试和清晰的方式,因为这种方式动作依赖于从外部提供的参数