как передать параметр из действия в код ActionFilterAttribute

у меня есть ActionFilterAttribute, как показано ниже

class MyCustomRouteConstraint : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (something == 1) //i know there is no something variable
        { 
           // do something
        }
        base.OnActionExecuting(filterContext);
    }

}

как видите, в моем коде нет переменной с каким-либо именем. но я хочу использовать переменную с именем как-то в своем действии.

    public ActionResult Index()
    {
        int something = 1;
        return View();
    }

    public ActionResult About()
    {
        int something = 2;
        return View();
    }

    public ActionResult Contact()
    {
        int something = 1;
        return View();
    }

person brtb    schedule 12.08.2013    source источник
comment
возможный дубликат Как передать переменные в пользовательский ActionFilter в приложении ASP.NET MVC   -  person Imad Alazani    schedule 16.08.2013


Ответы (5)


Я думаю, вам нужно OnActionExecuted. Я не тестировал.

class MyCustomRouteConstraint : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var something = Convert.ToInt32(filterContext.RouteData.Values["something"]);
        if(something == 1)
        {
            //do something
        }
        base.OnActionExecuting(filterContext);
    }
}
person Satpal    schedule 12.08.2013

OnActionExecuting вызывается платформой ASP.NET MVC ПЕРЕД выполнением метода действия. Поэтому нет смысла инициализировать переменную something в теле действия. Но все же, если вы собираетесь переопределить какой-либо метод, который вызывается ПОСЛЕ выполнения метода действия, вы, вероятно, можете использовать ViewBag для инициализации переменной в контроллере, а затем получить ее значение с помощью filterContext.

person Maksym Strukov    schedule 12.08.2013

Вы также используете ViewBag для этого.

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.Controller.ViewBag.SommeVariable = "Test";
    }

И в вашем действии

    public ActionResult Index()
    {
        var variable = ViewBag.SommeVariable;
        return View();
    }
person Nilesh    schedule 12.08.2013

Для этого я использую инъекцию зависимостей структурной карты. Посмотрите здесь несколько фрагментов:

namespace something.Infrastructure.ActionFilters {

  public class PlatformAuthorizeAttribute : AuthorizeAttribute
  {
      public IRepository<User> UserRepo { get; set; }

      public override void OnAuthorization(AuthorizationContext filterContext)
      {
          base.OnAuthorization(filterContext);

          if (WebSecurity.Initialized && filterContext.HttpContext.User.Identity.IsAuthenticated)
          {
              if (filterContext.HttpContext.User.IsInRole("Banned"))
              {
                  WebSecurity.Logout();
                  filterContext.Result = new RedirectToRouteResult(
                      new RouteValueDictionary
                          {
                            {"Controller", "Home"},
                            {"Action", "Banned"},
                            {"Area", ""}
                          });
              }
              UserRepo.Dispose();
              UserRepo = null;
          }  
      }
  }
}

А затем инициализируйте следующее сопоставление в вашем классе структуры IoC:

public static class IoC
{
    public static IContainer Initialize()
    {
        ObjectFactory.Initialize(x =>
            {
                x.Scan(scan =>
                    {
                        scan.TheCallingAssembly();
                        scan.WithDefaultConventions();
                    });
                x.SetAllProperties(pset =>
                    {
                        pset.WithAnyTypeFromNamespace("something.Infrastructure.ActionFilters");
                        pset.OfType<IRepository<User>>();
                    });
            });
        return ObjectFactory.Container;
    }
}

Я думаю, что это самый чистый способ снабдить ваши фильтры действий свойствами. Обратите внимание, что в моем примере я использовал собственный атрибут AuthorizeAttribute. Вам нужно будет изменить его на ActionFilterAttribute и использовать переопределение метода OnActionExecuting для доступа к свойствам.

person Bastaspast    schedule 12.08.2013

Используйте 1_

HttpContext.Items["something"] = 1;

В ActionFilter вы можете получить к нему доступ как:

var something = (int)filterContext.HttpContext.Items["something"];

Однако вашим примером фильтра действий является OnActionExecuting; это будет выполнено до выполнения любого из ваших действий Index/About. Таким образом, вы должны инициализировать «что-то» где-то еще в соответствии с вашими потребностями (например, внутри метода OnActionExecuting контроллера).

person Varun K    schedule 12.08.2013