Есть ли какие-либо атрибуты, относящиеся к AJAX, которые нужно установить для действий контроллера ASP.NET MVC? - PullRequest
44 голосов
/ 02 июля 2011

Я хочу использовать частичные представления с вызовами AJAX в ASP.NET MVC, и я впервые использую его.Я просто искал, чтобы узнать, есть ли что-то особенное, что я должен знать заранее, и один из них, который меня интересует, это посмотреть, есть ли какой-то специальный атрибут, который должен быть установлен или связан с вызовами AJAX?Что-то вроде [ChildActionOnly] или [HttpGet]

Ответы [ 6 ]

79 голосов
/ 02 июля 2011

Я не думаю, что есть встроенный атрибут для ajax, но его не так сложно создать. Вы можете создать фильтр AjaxOnly, например

public class AjaxOnlyAttribute : ActionMethodSelectorAttribute 
    {
        public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
        {
            return controllerContext.RequestContext.HttpContext.Request.IsAjaxRequest();
        }
    }

и украсьте ваши методы действия как

[AjaxOnly]
public ActionResult ajaxMethod()
{

}

Посмотрите на этот пост , чтобы найти другой способ реализации этого атрибута

18 голосов
/ 03 июля 2011

ASP.NET MVC предоставляет метод расширения для проверки того, является ли запрос запросом Ajax.Вы можете использовать его, чтобы решить, хотите ли вы вернуть частичное представление или результат json вместо обычного представления.

if (Request.IsAjaxRequest())
{
    return PartialView("name");
}
return View();

Чтобы ограничить метод действия только вызовами Ajax, вы можете написать собственный атрибут.В случае обычного запроса этот фильтр вернет исключение http 404 not found.

[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);
        }
     }
}

Вы можете использовать его следующим образом:

[AjaxOnly]
public ActionResult Index() {
    // do something awesome
}
4 голосов
/ 22 февраля 2014

Дополнительный ответ Мухаммеда, позволяющий вам указать, что это также не должен быть запрос ajax:

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();
    }
}

Это позволяет вам делать такие вещи, как ...

[Ajax]
public PartialViewResult AjaxUpdatingPage() {
    return PartialView();
}

[Ajax(false)]
public ViewResult NotAjaxUpdatingPage() {
    return View();
}
3 голосов
/ 18 января 2012

В коллекции ASP.NET MVC 3 Futures имеется атрибут [AjaxOnly] . Это часть официального сайта ASP.NET MVC Codeplex , которая предоставляет функции до их официального включения в будущую версию ASP.NET MVC.

Вы можете скачать его здесь . Чтобы использовать его, добавьте ссылку на сборку Microsoft.Web.Mvc , входящую в комплект поставки.

Существует объяснение атрибута на этой странице, наряду со всеми другими замечательными функциями, которые вы можете использовать.

2 голосов
/ 06 февраля 2014

мое решение следует реализации [ChildActionOnly]:

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
            ));
    }
}
0 голосов
/ 14 февраля 2018

Для тех, кто ищет решение .NET Core, оно немного сложнее, поскольку IsAjaxRequest() больше не доступен.

Ниже приведен код, который я использовал в производстве для нескольких проектов.

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;
  }
}
...