Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在ASP.NET MVC 2中向自定义ActionFilter传递参数?_C#_Asp.net_Asp.net Mvc_Action Filter - Fatal编程技术网

C# 如何在ASP.NET MVC 2中向自定义ActionFilter传递参数?

C# 如何在ASP.NET MVC 2中向自定义ActionFilter传递参数?,c#,asp.net,asp.net-mvc,action-filter,C#,Asp.net,Asp.net Mvc,Action Filter,我正在尝试创建一个自定义ActionFilter,它对从控制器传递给它的一组参数进行操作 到目前为止,我的客户ActionFilter如下所示: public class CheckLoggedIn : ActionFilterAttribute { public IGenesisRepository gr { get; set; } public Guid memberGuid { get; set; } public override void OnActionEx

我正在尝试创建一个自定义ActionFilter,它对从控制器传递给它的一组参数进行操作

到目前为止,我的客户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);
    }
}
    [CheckLoggedIn(gr = genesisRepository, memberGuid = md.memberGUID)]
    public ActionResult Home(MemberData md)
    {
        return View(md);
    }
genesisRepository
md
正在控制器的构造函数中设置

我无法编译这个。我得到的错误是:

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
是否与
genesreport
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);
    }
}

只能对属性属性使用常量值;有关完整解释,请参见。属性本质上是添加到类型中的元数据。它们只能使用
const
值,而不能使用实例变量。在您的情况下,您需要传入
genisisRepository
等的实例变量。这将无法编译,因为它们不是编译时常量

为了实现这一点,您应该研究操作过滤器的依赖项注入,通常使用IoC容器

此外,如果您的ActionFilter正在执行post ActionResult操作,例如
OnActionExecuted
,则您可能不需要在路由数据中存储某些内容:

public ActionResult Index()
{
  ControllerContext.RouteData.DataTokens.Add("name", "value");
  return View();
}

这是一个使这项工作的方法。您可以从ActionFilter对象访问ControllerContext,从而访问控制器。您只需将控制器强制转换为该类型,就可以访问任何公共成员

鉴于此控制器:

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);
    }
}
公共类CheckLoggedIn:ActionFilterAttribute
{
公共IGenesisRespository gr{get;set;}
公共Guid成员Guid{get;set;}
公共覆盖无效OnActionExecuting(ActionExecutingContext filterContext)
{
/*如何获取控制器*/
var controllerUsingThisAttribute=((GenesisController)filterContext.Controller);
/*现在,您可以使用控制器中的公共属性*/
gr=controllerUsingThisAttribute.genesisRepository;
memberGuid=(controllerUsingThisAttribute.memberGuid;
成员thisMember=gr.GetActiveMember(memberGuid);
Member bottomMember=gr.GetMemberOnBottom();

如果(thisMember.Role.Tier+1)提供进一步的指导…依赖注入是这种情况下的理想解决方案;服务位置是另一个(更简单)也可以考虑。嗯……我不确定这是可能的。<代码> M.MeMyGuIDID<代码>绑定到会话,并且不能是const,因为站点需要访问更新登录数据。因为我不想对特定的会话密钥创建依赖项。我宁愿检查GULAL..ASPX.CS会显示绑定和未来的开发人员可以很容易地进行更改将不在URL中的内容添加到路由数据中是一种非常可怕的数据存储方式。这会导致难以发现的错误。--依赖项注入并不能真正帮助解决此问题。任何为ActionFilter提供存储库的技术都会起作用。现在当然DI最好帮助停止服务位置问题,但这不是解决方案,只是启用解决方案的一种方法。关于如何实现这一点的好文章:您不需要IoC来注入它,但IoC可能会使它更容易。您可以在筛选器配置中声明筛选器,将其依赖项注入构造函数,然后注册筛选器。好吧,这让我明白了离解决方案更近了。谢谢jfar。不过actionFilter将在多个控制器之间使用。我在获取控制器时遇到很多问题。
var thisController=((MemberController)ControllerContext.controller)
返回错误:
非静态字段、方法或属性'System.Web.Mvc.ControllerContext.Controller.get'
@quakkels-Oops需要对象引用,请在我的头顶上执行。您可以通过
filterContext.Controller
获取控制器。也更新答案。
[CheckLoggedIn](gr=genesisRepository,memberGuid=md.memberGuid)]
???它是如何工作的?正如@DanP所说,您只能对属性属性使用常量值。我也注意到了这一点。18票赞成一个无法编译的答案。我想知道这是否是一个记录。您的问题很好,但解决方案比问题更棒。我正在寻找一个将参数发送到全局筛选器属性的解决方案但是,这对我来说就像是止痛药:)