I have added a filter to get "grouping" value either from query params or from body, but breakpoint on filter is only hit when I have passed query params to method, else not
FilterCode:
public class GroupingCodeFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var httpContext = context.HttpContext;
var request = httpContext.Request;
if (request.Query.TryGetValue("grouping", out var groupingFromQuery))
{
httpContext.Items["grouping"] = groupingFromQuery.ToString();
}
else if (context.ActionArguments.TryGetValue("model", out var value) &&
value is GridParamsModel gridModel &&
gridModel.ParameterDictionary != null &&
gridModel.ParameterDictionary.TryGetValue("groupingCode", out var groupingCodeObj))
{
var groupingCode = groupingCodeObj?.ToString();
if (!string.IsNullOrEmpty(groupingCode))
{
httpContext.Items["grouping"] = groupingCode;
}
}
await next();
}
}
Method on which filter works :
[HttpPost("AddRecord")]
[GroupingCodeFilter]
[DynamicTask(typeof(TaxCalendarAPIService.Controllers.GridServiceControllers.MaintainPaymentTypesController), "GetDynamicAaddRecordTaskAttributeID", "grouping")]
public async Task<IActionResult> AddRecord([FromQuery] string grouping, [FromBody] CodeListDTO model) {}
Method on which filter does not work :
[HttpPost("GetContent")]
[GroupingCodeFilter]
[DynamicTask(typeof(...), "GetDynamicTaskAttributeID", "grouping")]
public async Task<IActionResult> GetContent([FromBody] GridParamsModel model)
{}
On GetContent Method filter works if I pass queryparams or if I comment DynamicTaskAttribute
I have even tried to register filter in startup and then use it as but nothing worked
[ServiceFilter(typeof(GroupingCodeFilter))]
GetMethod shows error that The given key 'grouping' was not present in the dictionary
Somebody please help. I am just tired of this
I have added a filter to get "grouping" value either from query params or from body, but breakpoint on filter is only hit when I have passed query params to method, else not
FilterCode:
public class GroupingCodeFilter : IAsyncActionFilter
{
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var httpContext = context.HttpContext;
var request = httpContext.Request;
if (request.Query.TryGetValue("grouping", out var groupingFromQuery))
{
httpContext.Items["grouping"] = groupingFromQuery.ToString();
}
else if (context.ActionArguments.TryGetValue("model", out var value) &&
value is GridParamsModel gridModel &&
gridModel.ParameterDictionary != null &&
gridModel.ParameterDictionary.TryGetValue("groupingCode", out var groupingCodeObj))
{
var groupingCode = groupingCodeObj?.ToString();
if (!string.IsNullOrEmpty(groupingCode))
{
httpContext.Items["grouping"] = groupingCode;
}
}
await next();
}
}
Method on which filter works :
[HttpPost("AddRecord")]
[GroupingCodeFilter]
[DynamicTask(typeof(TaxCalendarAPIService.Controllers.GridServiceControllers.MaintainPaymentTypesController), "GetDynamicAaddRecordTaskAttributeID", "grouping")]
public async Task<IActionResult> AddRecord([FromQuery] string grouping, [FromBody] CodeListDTO model) {}
Method on which filter does not work :
[HttpPost("GetContent")]
[GroupingCodeFilter]
[DynamicTask(typeof(...), "GetDynamicTaskAttributeID", "grouping")]
public async Task<IActionResult> GetContent([FromBody] GridParamsModel model)
{}
On GetContent Method filter works if I pass queryparams or if I comment DynamicTaskAttribute
I have even tried to register filter in startup and then use it as but nothing worked
[ServiceFilter(typeof(GroupingCodeFilter))]
GetMethod shows error that The given key 'grouping' was not present in the dictionary
Somebody please help. I am just tired of this
Share Improve this question edited Mar 27 at 3:54 Ishani Bhatt asked Mar 27 at 3:25 Ishani BhattIshani Bhatt 213 bronze badges 1 |1 Answer
Reset to default 0Accordting to the symptom, the exception is due to DynamicTask
is trying to get grouping
but failed. Since you didn't share what DynamicTask
does in your question, I could only try to mock the exception.
Firstly, I make DynamicTask
to implement IActionFilter
like
public class DynamicTaskAttribute : Attribute, IAsyncActionFilter
{
private readonly Type _controllerType;
private readonly string _methodName;
private readonly string _key;
public DynamicTaskAttribute(Type controllerType, string methodName, string key)
{
_controllerType = controllerType;
_methodName = methodName;
_key = key;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var httpContext = context.HttpContext;
if (!httpContext.Items.TryGetValue(_key, out var value))
{
throw new KeyNotFoundException($"The given key '{_key}' was not present in the dictionary.");
}
var groupingValue = value?.ToString();
await next();
}
}
but I find that GroupingCodeFilter
will execute before DynamicTaskAttribute
because you have [GroupingCodeFilter]
above [DynamicTask]
. And because of the execution order, even if I don't have /GetContent?grouping=asdf
in the url, my code still worked because GroupingCodeFilter
already get value from GridParamsModel
model and set it to httpContext.Items["grouping"]
. Therefore, I'm sure DynamicTask
is not an action filter but something else executed before Action Filter, for example, it's a resource filter/authorization filter/custom middleware.
Anyway, to fix this issue, we need to make sure there's an existing grouping
key inside the Dictionary or make grouping
key nullable. To ensure an existing grouping
key, if we can adjust the execution order, then enforce GroupingCodeFilter
to run before DynamicTask
. If not, maybe we can adjust the input parameter in frontend codes, like getting the groupingCode from request content and append it to the url.
DynamicTask
attribute provide? You mentioned taht comment this attribute could solve the issue. – Tiny Wang Commented Mar 27 at 6:57