Как я могу отправить данные в фильтр действий после выполнения контроллера в ASP. NET MVC? - PullRequest
0 голосов
/ 17 марта 2020

Следующее моё действие в контроллере. Мне нужно передать ProductId и Quantity в фильтр SessionCheck. Есть ли другой способ, кроме TempData?

[SessionCheck]
[HttpPost]
public ActionResult AddToCart(int ProductId, int Quantity)
{
    try
    {
        //my code here 

        return RedirectToAction("Cart");
    }
    catch (Exception error)
    {
        throw error;
    }
}

И мой фильтр действий следующий:

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
  // my code here
}

1 Ответ

0 голосов
/ 17 марта 2020

Хороший вопрос. Насколько я знаю, невозможно напрямую вызывать параметры непосредственно из вашего фильтра - даже если вы можете получить метаданные о параметрах с помощью ActionDescriptor.GetParameters() метода .

Исходные значения

Однако вы можете получить доступ к этим значениям непосредственно из их исходной коллекции, используя либо RequestContext.RouteData, либо RequestContext.HttpContext Request свойство , которое может извлекать данные из Form, QueryString или других коллекций запросов. Все это свойства вне ActionExecutedContext.

Пример

Так, например, если ваши значения извлекаются из коллекции форм - что, я полагаю, может иметь место, поскольку это действие [HttpPost] - ваш код может выглядеть что-то вроде:

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
  var request = filterContext.RequestContext.HttpContext.Request;
  Int32.TryParse(request.Form.Get("ProductId"), out var productId);
  Int32.TryParse(request.Form.Get("Quantity"), out var quantity);
}

Проверка

Имейте в виду, что технически ваш ActionFilterAttribute может быть применен к любому числу действий, поэтому вы должны знать об этом, а не предположим , что эти параметры будут доступны. Вы можете использовать свойство ActionDescriptor.ActionName для проверки контекста, если необходимо:

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
  if (filterContext.ActionDescriptor.ActionName.Equals(nameof(MyController.AddToCart)) 
  {
    //Retrieve values
  }
}

Или, альтернативно, вы можете использовать ActionDescriptor.GetParameters() метод , упомянутый выше, чтобы просто оценить, существуют ли параметры, независимо от того, как называется действие.

Предостережения

У этого подхода есть некоторые ограничения. В частности:

  1. Он не сможет получить значения внутренних вызовов к действию, а
  2. Он не будет выполнять привязку модели, что может быть проблемой. для более сложных объектов.

Другие рамки

Вы указываете ASP. NET MVC. Для тех, кто читает это и использует ядро ​​ASP. NET, библиотеки классов немного отличаются и предлагают некоторые дополнительные функции (например, TryGetValue() для вызовов методов HttpRequest). Кроме того, он также предоставляет доступ к коллекции BoundProperties, которая может предоставлять дополнительные опции, хотя я еще не копался в этих данных для подтверждения.

...