C# 使用筛选器时,如何从ResultExecutingContext获取操作的参数
我正在创建一个自定义结果过滤器,该过滤器实现IAsyncResultFilter接口。在这个过滤器中,我需要操作返回的实际值,但我还需要该操作的一个参数(这个参数来自查询字符串,用于分页)。 问题是,我还没有找到直接从ResultExecutingContext获取参数值的方法,ResultExecutingContext是我在结果过滤器实现中可用的变量 我尝试使用context.ActionDescriptor.Parameters获取参数值,但它是ParameterDescriptor的集合,我无法从中获取实际值,只是ParameterDescriptor的一个实例 我已经能够从标题和查询字符串本身获取mediaType,但不能从绑定到PagingModel类型的查询字符串中获取mediaType 有没有办法从ResultExecutingContext变量获取此参数C# 使用筛选器时,如何从ResultExecutingContext获取操作的参数,c#,asp.net-core,.net-core,asp.net-core-mvc,asp.net-core-webapi,C#,Asp.net Core,.net Core,Asp.net Core Mvc,Asp.net Core Webapi,我正在创建一个自定义结果过滤器,该过滤器实现IAsyncResultFilter接口。在这个过滤器中,我需要操作返回的实际值,但我还需要该操作的一个参数(这个参数来自查询字符串,用于分页)。 问题是,我还没有找到直接从ResultExecutingContext获取参数值的方法,ResultExecutingContext是我在结果过滤器实现中可用的变量 我尝试使用context.ActionDescriptor.Parameters获取参数值,但它是ParameterDescriptor的集合
//来自ApiController的操作
[HttpGet]
[AddPaginationHeader]
公共异步任务Get([FromQuery]PagingModel PagingModel,
[FromHeader(Name=“Accept”)]字符串媒体类型{
var pagedCollection=repository.GetPage(分页模型);
var shapedCollection=ShapeCollectionOfData(pagedCollection);
返回Ok(shapedCollection);
}
//AddPaginationHeader实现(结果过滤器)
ResultExecutionAsync上的公共任务(ResultExecutionContext,ResultExecutionDelegate next){
var result=context.result作为ObjectResult;
如果(结果?.Value!=null&&result?.StatusCode>=200&&
结果?.StatusCode<300){
//尝试获取pagingModel(但获取ParameterDescriptor类型)
var pagingModel=context.ActionDescriptor.Parameters.Where(t=>t.Name.Equals(“pagingModel”)).FirstOrDefault();
//获取媒体类型
string mediaType=context.HttpContext.Request.Headers[“Accept”]
//获取查询字符串本身
字符串queryString=context.HttpContext.Request.queryString.ToString();
//需要分页模型的实际逻辑的实现
// ...
next();
}
返回Task.CompletedTask;
}
要获取分页模型
,您可以尝试tryupdatemodelsync
类似的方法
public class AddPaginationHeader : Attribute, IAsyncResultFilter
{
// AddPaginationHeader Implementation (Result Filter)
public async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
//PagingModel model = new PagingModel();
//await controller.TryUpdateModelAsync(model);
var result = context.Result as ObjectResult;
if (result?.Value != null && result?.StatusCode >= 200 &&
result?.StatusCode < 300)
{
// Trying to get the pagingModel (but getting a ParameterDescriptor type)
var controller = context.Controller as Controller;
var parameterDescriptor = context.ActionDescriptor.Parameters.Where(t => t.Name.Equals("pagingModel")).FirstOrDefault();
var parameter = Activator.CreateInstance(parameterDescriptor.ParameterType);
await controller.TryUpdateModelAsync(parameter, parameterDescriptor.ParameterType, "");
var pagingModel = parameter;
//Getting the media type
string mediaType = context.HttpContext.Request.Headers["Accept"];
// Getting the query string itself
string queryString = context.HttpContext.Request.QueryString.ToString();
//Implementation of the actual logic that needs the paging model
// ...
next();
}
//return Task.CompletedTask;
}
}
public类AddPaginationHeader:属性,IAsyncResultFilter
{
//AddPaginationHeader实现(结果过滤器)
ResultExecutionAsync上的公共异步任务(ResultExecutionContext,ResultExecutionDelegate next)
{
//PagingModel模型=新的PagingModel();
//wait controller.tryupdatemodelsync(model);
var result=context.result作为ObjectResult;
如果(结果?.Value!=null&&result?.StatusCode>=200&&
结果?.StatusCode<300)
{
//尝试获取pagingModel(但获取ParameterDescriptor类型)
var controller=context.controller作为控制器;
var parameterDescriptor=context.ActionDescriptor.Parameters.Where(t=>t.Name.Equals(“pagingModel”)).FirstOrDefault();
var参数=Activator.CreateInstance(parameterDescriptor.ParameterType);
wait controller.tryupdatemodelsync(参数,parameterDescriptor.ParameterType,“”);
var pagingModel=参数;
//获取媒体类型
string mediaType=context.HttpContext.Request.Headers[“Accept”];
//获取查询字符串本身
字符串queryString=context.HttpContext.Request.queryString.ToString();
//需要分页模型的实际逻辑的实现
// ...
next();
}
//返回Task.CompletedTask;
}
}
基于Tao的回答,我创建了一个很好的静态方法,允许您从控制器获取任何类型的任何参数:
私有静态异步任务GetParameterFromAction(ResultExecutingContext,string parameterName){
var parameterDescriptor=context.ActionDescriptor.Parameters.Where(t=>t.Name.Equals(parameterName)).FirstOrDefault();
ControllerBase controller=context.controller作为ControllerBase;
TParameter参数=(TParameter)Activator.CreateInstance(parameterDescriptor.ParameterType);
wait controller.tryupdatemodelsync(参数,parameterDescriptor.ParameterType,string.Empty);
返回参数;
}
在.net core 3.1中,您可以在过滤器中检索参数及其值,如下所示:
foreach (var argument in context.ActionArguments)
{
object parameterValue = argument.Value;
string parameterName = argument.Key;
}
此代码检索基本数据类型的参数值。您可以扩展此代码以处理对象和值列表。
参数.Value
属性将包含对象属性或值列表的值。尝试在context.routedData中查找。它应该有所有的钥匙和价值石涛,非常感谢。它起作用了,我只需要对你的答案做一个小小的改变。我必须将控制器转换为ControllerBase,而不仅仅是控制器。我在Microsoft.AspNetCore.Mvc中找不到控制器类