When a PJAX request is sent, it is always supposed to include this header in the HTTP Request:
X-PJAX: true
You can redirect the different requests by adding a custom ActionMethodSelectorAttribute
that checks if the X-PJAX
header is present.
Add this custom Attribute
class to your solution:
public class AcceptHeaderAttribute : ActionMethodSelectorAttribute
{
public string HeaderName { get; set; }
public string HeaderValue { get; set; }
public AcceptHeaderAttribute(string headerName, string headerValue = null)
{
if (String.IsNullOrWhiteSpace(headerName))
throw new ArgumentNullException("headerName");
HeaderName = headerName;
HeaderValue = headerValue;
}
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
if (controllerContext == null)
throw new ArgumentNullException("controllerContext");
var incomingHeader = controllerContext.HttpContext.Request.Headers[HeaderName];
var headerExists = String.IsNullOrWhiteSpace(incomingHeader);
// NOTE: can optionally change this to Contains, or add a parameter for that.
var valueCorrect = String.Equals(incomingHeader, HeaderValue, StringComparison.OrdinalIgnoreCase);
return (String.IsNullOrWhiteSpace(HeaderValue)
? headerExists
: valueCorrect);
}
}
You can then set different Action
for PJAX requests versus direct user requests:
[AcceptHeader("X-PJAX", "true")]
public ActionResult About(string myInput)
{
ViewBag.Test = "This is a PJAX request";
return View();
}
public ActionResult About()
{
ViewBag.Test = "This is a normal request";
return View();
// or redirect them to root page
return RedirectToAction("Index");
}
If you only care to check that the Header exists in the HTTP Request, and don't care that the value is correct, you can simplify the usage to just:
[AcceptHeader("X-PJAX")]