在 ASP.NET MVC 中执行控制器后如何将数据发送到 Action Filter?
How Can I Send Data to the Action Filter after Execution of the controller in ASP.NET MVC?
以下是我在控制器中的动作。我需要将 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
}
好问题。据我所知,无法从您的过滤器中直接 调用参数——即使您可以通过ActionDescriptor.GetParameters()
方法。
源值
但是,您可以使用 RequestContext.RouteData
, or the RequestContext.HttpContext
’s Request
property, which can retrieve data from the Form
, QueryString
, or other request collections. All of these are properties off of the ActionExecutedContext
从它们的 source 集合中直接访问这些值。
例子
因此,例如,如果您的值是从表单集合中检索的——我认为可能是这种情况,因为这是一个 [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()
方法来简单地评估参数是否存在,而不管动作的名称是什么。
注意事项
这种方法有一些局限性。最值得注意的是:
- 它将无法检索对操作的内部调用的值,并且
- 它不会执行任何模型绑定,这对于更复杂的对象来说可能是个问题。
其他框架
您指定 ASP.NET MVC。对于使用 ASP.NET Core 阅读本文的任何人来说,class 库有点不同,并提供一些额外的功能(例如 TryGetValue()
用于调用 HttpRequest
方法)。此外,它还提供对 BoundProperties
集合的访问, 可能 提供额外的选项——尽管我还没有深入研究这些数据来确认。
以下是我在控制器中的动作。我需要将 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
}
好问题。据我所知,无法从您的过滤器中直接 调用参数——即使您可以通过ActionDescriptor.GetParameters()
方法。
源值
但是,您可以使用 RequestContext.RouteData
, or the RequestContext.HttpContext
’s Request
property, which can retrieve data from the Form
, QueryString
, or other request collections. All of these are properties off of the ActionExecutedContext
从它们的 source 集合中直接访问这些值。
例子
因此,例如,如果您的值是从表单集合中检索的——我认为可能是这种情况,因为这是一个 [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()
方法来简单地评估参数是否存在,而不管动作的名称是什么。
注意事项
这种方法有一些局限性。最值得注意的是:
- 它将无法检索对操作的内部调用的值,并且
- 它不会执行任何模型绑定,这对于更复杂的对象来说可能是个问题。
其他框架
您指定 ASP.NET MVC。对于使用 ASP.NET Core 阅读本文的任何人来说,class 库有点不同,并提供一些额外的功能(例如 TryGetValue()
用于调用 HttpRequest
方法)。此外,它还提供对 BoundProperties
集合的访问, 可能 提供额外的选项——尽管我还没有深入研究这些数据来确认。