using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Primitives;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace MyApplication.Whatever
{
public class QueryStringConstraintAttribute : ActionMethodSelectorAttribute
{
private readonly IEnumerable<string> _queryParamNames;
private readonly IEnumerable<string> _optionalParamNames;
public QueryStringConstraintAttribute(string queryParamNames, string optionalParamNames = null)
{
if (string.IsNullOrWhiteSpace(queryParamNames))
{
throw new InvalidOperationException($"{nameof(queryParamNames)} cannot be null or empty");
}
_queryParamNames = queryParamNames.Split(",");
if (!string.IsNullOrWhiteSpace(optionalParamNames))
{
_optionalParamNames = optionalParamNames.Split(",");
}
}
public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
{
int optParamCount = 0;
foreach (var qpn in _queryParamNames)
{
var value = routeContext.HttpContext.Request.Query[qpn];
if (StringValues.IsNullOrEmpty(value))
{
return false;
}
}
foreach (var opn in _optionalParamNames ?? Enumerable.Empty<string>())
{
var value = routeContext.HttpContext.Request.Query[opn];
if (!StringValues.IsNullOrEmpty(value))
{
optParamCount++;
}
}
var uniqueParamCounts = routeContext.HttpContext.Request.Query.Count;
if ((uniqueParamCounts - optParamCount) > _queryParamNames.Count())
{
return false;
}
return true;
}
}
}
//usage (decorate methods like)
[QueryStringConstraint("activealtid")]
[QueryStringConstraint("role,assignment", "includealtids")]