I had the situation where I wanted to do query parameter (not form parameter) xss handling* for all of my MVC flows (and hence ActionFilter was ideal); but even on Microsoft docs I couldn't find a good implementation of this (Which I thought is a very typical scenario)
So creating this wiki format of Q&A (will post my code as an answer) to publish the implementation which solved my scenario
*When I say xss handling, I wanted the code to redirect to login page (rather than let ASP.NET MVC redirect it to lets say the error page which we can control via web.config customErrors mode="On")
Here is the implementation that worked for the use-case I mention in the question
using System;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security.AntiXss;
namespace SomeAttribute
{
public class QueryParamsXssValidate : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
try
{
var qs = filterContext.HttpContext.Request.QueryString;
foreach (var keyRecvd in qs.AllKeys)
{
var keyEncd = AntiXssEncoder.HtmlEncode(keyRecvd);
if (keyEncd != keyRecvd)
{
throw new ArgumentException($"Potentially dangerous keyRecvd: {keyRecvd}");
}
var valRecvd = qs[keyRecvd];
var valEncd = AntiXssEncoder.HtmlEncode(valRecvd);
if (valEncd != valRecvd)
{
throw new ArgumentException($"Potentially dangerous valRecvd: {valRecvd}");
}
}
}
catch (ArgumentException e)
{
//logging
loginRedirect(filterContext); //alternatively, create ExceptionHandlerAttribute and rethrow here
}
}
private void loginRedirect(ActionExecutingContext filterContext)
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{"controller", "main"},
{"action", "login"},
{"error", filterContext.HttpContext.Request.QueryString["error"] ?? string.Empty}
});
}
}
}