我正在尝试创建一个自定义 ActionFilter,它对从 Controller 传递给它的一组参数进行操作。
到目前为止,我的客户 ActionFilter 看起来像这样:
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);
}
}
我知道我仍然需要检查空值等,但我不明白为什么 gr
和 memberGuid
没有成功传递。我这样称呼这个过滤器:
[CheckLoggedIn(gr = genesisRepository, memberGuid = md.memberGUID)]
public ActionResult Home(MemberData md)
{
return View(md);
}
genesisRepository
和 md
正在 Controller 的构造函数中设置。
我无法编译它。我得到的错误是:
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
我仔细检查了 gr
和 memberGuid
与 genesisRepority
和 md.memberGUID
的类型相同,什么是导致这些错误的原因吗?
解决方案
感谢 jfar 提供解决方案。
这是我最终使用的过滤器:
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);
}
}
最佳答案
这是实现此功能的一种方法。您可以从 ActionFilter 对象访问 ControllerContext 和 Controller。您需要做的就是将您的 Controller 转换为该类型,然后您就可以访问任何公共(public)成员。
给定这个 Controller :
public GenesisController : Controller
{
[CheckLoggedIn()]
public ActionResult Home(MemberData md)
{
return View(md);
}
}
ActionFilter 看起来像
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);
}
}
当然,这是假设 ActionFilter 未在多个 Controller 中使用,并且您可以接受耦合。另一种选择是创建一个具有共享属性的 ICheckedLoggedInController 接口(interface),然后简单地转换为该接口(interface)。
关于c# - 如何将参数传递给 ASP.NET MVC 2 中的自定义 ActionFilter?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4348071/