The X-Requested-With header returns a string that indicates whether it's an Ajax request or not. An Ajax request will have this header set to XMLHttpRequest. This header value won't be present for normal GET and POST requests (non-Ajax requests).
So you could just write attribute like:
public class AjaxOnlyAttribute : ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor actionDescriptor)
{
if (routeContext.HttpContext.Request.Headers != null &&
routeContext.HttpContext.Request.Headers.ContainsKey("X-Requested-With") &&
routeContext.HttpContext.Request.Headers.TryGetValue("X-Requested-With", out StringValues requestedWithHeader))
{
if (requestedWithHeader.Contains("XMLHttpRequest"))
{
return true;
}
}
return false;
}
}
Then use that like :
[AjaxOnlyAttribute]
public IActionResult Search()
{
return PartialView();
}
Or you can directly check that in specific action :
string method = HttpContext.Request.Method;
string requestedWith =
HttpContext.Request.Headers["X-Requested-With"];
if (method == "POST")
{
if (requestedWith == "XMLHttpRequest")
{
// code goes here
}
}