如何将参数传递到ASP.NET MVC 2自定义ActionFilter? [英] How to pass parameters to a custom ActionFilter in ASP.NET MVC 2?
问题描述
我试图创造出一组将被传递给它从控制器运行参数的自定义ActionFilter。
到目前为止,我的客户ActionFilter看起来是这样的:
公共类CheckLoggedIn:ActionFilterAttribute
{
公共IGenesisRepository克{搞定;组; }
公众的Guid memberGuid {搞定;组; } 公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
{
会员thisMember = gr.GetActiveMember(memberGuid);
会员bottomMember = gr.GetMemberOnBottom(); 如果(thisMember.Role.Tier< = bottomMember.Role.Tier)
{
filterContext
.HttpContext
。响应
.RedirectToRoute(新{控制器=会员,行动=登录});
} base.OnActionExecuting(filterContext);
}
}
我知道我还需要检查空值,等等。但我不明白,为什么克
和 memberGuid
未成功传递。我打电话这样此次筛选:
[CheckLoggedIn(GR = genesisRepository,memberGuid = md.memberGUID)
公众的ActionResult主页(MemberData MD)
{
返回查看(MD);
}
genesisRepository
和 MD
在控制器的构造函数中被设置。
我没能得到这个编译。我得到的错误是:
错误1'克'是不是一个有效的命名特性参数,因为它不是一个有效的属性参数类型
错误2'memberGuid'不是一个有效的命名特性参数,因为它不是一个有效的属性参数类型
我仔细检查了该克
和 memberGuid
是一样的类型, genesisRepority
和 md.memberGUID
,是什么原因造成这些错误?
解决方案
感谢jfar为提供解决方案。
下面是我最终使用的过滤器:
公共类CheckLoggedIn:ActionFilterAttribute
{ 公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
{
变种thisController =((MemberController)filterContext.Controller); IGenesisRepository克= thisController.GenesisRepository;
GUID memberGuid =((MemberData)filterContext.HttpContext.Session [thisController.MemberKey])MemberGUID。 会员thisMember = gr.GetActiveMember(memberGuid);
会员bottomMember = gr.GetMemberOnBottom(); 如果(thisMember.Role.Tier> = bottomMember.Role.Tier)
{
filterContext.Result =新RedirectToRouteResult(
新RouteValueDictionary(
新{
控制器=会员,
行动=登陆
}));
} base.OnActionExecuting(filterContext);
}
}
这是一种方法,使这项工作。您可以从ActionFilter对象访问ControllerContext,因此控制器。所有你需要做的是投你的控制器的类型,你可以访问任何公共成员。
鉴于此控制器:
公共GenesisController:控制器
{
[CheckLoggedIn()]
公众的ActionResult主页(MemberData MD)
{
返回查看(MD);
}
}
ActionFilter看起来像
公共类CheckLoggedIn:ActionFilterAttribute
{
公共IGenesisRepository克{搞定;组; }
公众的Guid memberGuid {搞定;组; } 公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
{
/ *如何让控制器* /
变种controllerUsingThisAttribute =((GenesisController)filterContext.Controller); / *现在你可以从控制器使用的公共属性* /
GR = controllerUsingThisAttribute .genesisRepository;
memberGuid =(controllerUsingThisAttribute .memberGuid; 会员thisMember = gr.GetActiveMember(memberGuid);
会员bottomMember = gr.GetMemberOnBottom(); 如果(thisMember.Role.Tier< = bottomMember.Role.Tier)
{
filterContext
.HttpContext
。响应
.RedirectToRoute(新{控制器=会员,行动=登录});
} base.OnActionExecuting(filterContext);
}
}
当然,这是假设的ActionFilter不是跨多个控制器使用,你没事的耦合。另一个选项是使ICheckedLoggedInController接口与共享的属性和简单地投射到该代替
I'm trying to create a custom ActionFilter which operates on a set of parameters that would be passed to it from the controller.
So far, my customer ActionFilter looks like this:
public class CheckLoggedIn : ActionFilterAttribute
{
public IGenesisRepository gr { get; set; }
public Guid memberGuid { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Member thisMember = gr.GetActiveMember(memberGuid);
Member bottomMember = gr.GetMemberOnBottom();
if (thisMember.Role.Tier <= bottomMember.Role.Tier)
{
filterContext
.HttpContext
.Response
.RedirectToRoute(new { controller = "Member", action = "Login" });
}
base.OnActionExecuting(filterContext);
}
}
I know I still need to check for nulls, etc. but I can't figure out why gr
and memberGuid
aren't successfully being passed. I'm calling this Filter like this:
[CheckLoggedIn(gr = genesisRepository, memberGuid = md.memberGUID)]
public ActionResult Home(MemberData md)
{
return View(md);
}
genesisRepository
and md
are being set in the controller's constructor.
I'm not able to get this to compile. The error I get is:
Error 1 'gr' is not a valid named attribute argument because it is not a valid attribute parameter type
Error 2 'memberGuid' is not a valid named attribute argument because it is not a valid attribute parameter type
I double checked that gr
and memberGuid
were the same types as genesisRepority
and md.memberGUID
, What is causing these errors?
Solution
Thanks to jfar for offering a solution.
Here's the Filter I ended up using:
public class CheckLoggedIn : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var thisController = ((MemberController)filterContext.Controller);
IGenesisRepository gr = thisController.GenesisRepository;
Guid memberGuid = ((MemberData)filterContext.HttpContext.Session[thisController.MemberKey]).MemberGUID;
Member thisMember = gr.GetActiveMember(memberGuid);
Member bottomMember = gr.GetMemberOnBottom();
if (thisMember.Role.Tier >= bottomMember.Role.Tier)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(
new {
controller = "Member",
action = "Login"
}));
}
base.OnActionExecuting(filterContext);
}
}
This is a way to make this work. You have access to the ControllerContext and therefore Controller from the ActionFilter object. All you need to do is cast your controller to the type and you can access any public members.
Given this controller:
public GenesisController : Controller
{
[CheckLoggedIn()]
public ActionResult Home(MemberData md)
{
return View(md);
}
}
ActionFilter looks something like
public class CheckLoggedIn : ActionFilterAttribute
{
public IGenesisRepository gr { get; set; }
public Guid memberGuid { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
/* how to get the controller*/
var controllerUsingThisAttribute = ((GenesisController)filterContext.Controller);
/* now you can use the public properties from the controller */
gr = controllerUsingThisAttribute .genesisRepository;
memberGuid = (controllerUsingThisAttribute .memberGuid;
Member thisMember = gr.GetActiveMember(memberGuid);
Member bottomMember = gr.GetMemberOnBottom();
if (thisMember.Role.Tier <= bottomMember.Role.Tier)
{
filterContext
.HttpContext
.Response
.RedirectToRoute(new { controller = "Member", action = "Login" });
}
base.OnActionExecuting(filterContext);
}
}
Of course this is assuming the ActionFilter isn't used across multiple controllers and you're ok with the coupling. Another Option is to make a ICheckedLoggedInController interface with the shared properties and simply cast to that instead.
这篇关于如何将参数传递到ASP.NET MVC 2自定义ActionFilter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!