I want to use partial views with AJAX calls in ASP.NET MVC, and this is the first time I\'m using it. I just searched to see if there is anything special I should know befor
I don't think there is built in attribute for ajax, but you can create your own AjaxOnly
filter like this:
public class AjaxOnlyAttribute : ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
return controllerContext.RequestContext.HttpContext.Request.IsAjaxRequest();
}
}
And decorate your action methods like this:
[AjaxOnly]
public ActionResult AjaxMethod()
{
}
See Also: ASP.NET MVC Action Filter – Ajax Only Attribute for another way of implementing this
A spinoff of Muhammad's answer letting you specify that it mustn't be an ajax request as well:
using System.Web.Mvc;
public class AjaxAttribute : ActionMethodSelectorAttribute
{
public bool ajax { get; set; }
public AjaxAttribute() { ajax = true; }
public AjaxAttribute(bool a) { ajax = a; }
public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
return ajax == controllerContext.HttpContext.Request.IsAjaxRequest();
}
}
This lets you do things like...
[Ajax]
public PartialViewResult AjaxUpdatingPage() {
return PartialView();
}
[Ajax(false)]
public ViewResult NotAjaxUpdatingPage() {
return View();
}
my solution follows the [ChildActionOnly]
implementation:
public class AjaxOnlyAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
throw new ArgumentNullException("filterContext");
if (!filterContext.HttpContext.Request.IsAjaxRequest())
throw new InvalidOperationException(string.Format(
CultureInfo.CurrentCulture,
"The action '{0}' is accessible only by an ajax request.",
filterContext.ActionDescriptor.ActionName
));
}
}
ASP.NET MVC provides an extension method to check if an Request is an Ajax Request. You can use it to decide if you want to return a partial view or json result instead of a normal view.
if (Request.IsAjaxRequest())
{
return PartialView("name");
}
return View();
To limit an action method to Ajax calls only you can write a custom attribute. In case of a normal request this filter will return a 404 not found http exception.
[AttributeUsage(AttributeTargets.Method)]
public class AjaxOnlyAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!filterContext.HttpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 404;
filterContext.Result = new HttpNotFoundResult();
}
else
{
base.OnActionExecuting(filterContext);
}
}
}
you can use it like that:
[AjaxOnly]
public ActionResult Index() {
// do something awesome
}
For those looking for a .NET Core solution it's a little bit more involved, as IsAjaxRequest()
is no longer available.
Below is the code I've used in production on several projects to great effect.
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;
}
}
There is an [AjaxOnly] attribute provided in the ASP.NET MVC 3 Futures collection. It's a part of the official ASP.NET MVC Codeplex site that provides features before they are officially included in a future version of ASP.NET MVC.
You can download it here. To use it, add a reference to the Microsoft.Web.Mvc assembly included in the release package.
There is an explanation of the attribute on this page, along with all the other great features you can use.