是否有任何与 AJAX 相关的属性可以为 ASP.NET MVC 控制器操作设置?

发布于 2024-11-18 02:34:46 字数 175 浏览 6 评论 0原文

我想在 ASP.NET MVC 中使用带有 AJAX 调用的部分视图,这是我第一次使用它。我只是搜索了一下是否有什么特殊的东西我应该事先知道,其中我很好奇的就是看看是否有任何特殊的属性应该设置或与 AJAX 调用相关?类似于 [ChildActionOnly][HttpGet]

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 beforehand, and one of'em that I'm curious about, is to see if there is any special attribute that should be set or is related to AJAX calls? Something like [ChildActionOnly] or [HttpGet]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

初见终念 2024-11-25 02:34:47

ASP.NET MVC 提供了一个扩展方法来检查请求是否是 Ajax 请求。您可以使用它来决定是否要返回部分视图或 json 结果而不是普通视图。

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

要将操作方法​​限制为仅 Ajax 调用,您可以编写自定义属性。如果是正常请求,此过滤器将返回 404 未找到 http 异常。

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

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
}
打小就很酷 2024-11-25 02:34:47

Muhammad 答案的衍生内容,让您指定它也不能是 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();
}

更新 ASP.NET Core:

您将需要替换 usings和方法签名/主体具有以下内容...

using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Routing;
using System.Linq;

public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
{
    // Using ASP.NET 6 strongly typed header:
    return ajax == routeContext.HttpContext.Request.Headers.XRequestedWith.Contains("XMLHttpRequest");
    // Older versions:
    return ajax == routeContext.HttpContext.Request.Headers.Any(h => h.Key == "X-Requested-With" && h.Value.Contains("XMLHttpRequest"));
}

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

Update for ASP.NET Core:

You will need to replace the usings and method signature/body with the following...

using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Routing;
using System.Linq;

public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
{
    // Using ASP.NET 6 strongly typed header:
    return ajax == routeContext.HttpContext.Request.Headers.XRequestedWith.Contains("XMLHttpRequest");
    // Older versions:
    return ajax == routeContext.HttpContext.Request.Headers.Any(h => h.Key == "X-Requested-With" && h.Value.Contains("XMLHttpRequest"));
}
丶视觉 2024-11-25 02:34:47

ASP.NET MVC 3 Futures 集合中提供了一个 [AjaxOnly] 属性。它是官方 ASP.NET MVC Codeplex 网站的一部分,该网站在正式包含在未来版本中之前提供功能ASP.NET MVC 的。

您可以在此处下载它。要使用它,请添加对发布包中包含的 Microsoft.Web.Mvc 程序集的引用。

页面,以及您可以使用的所有其他强大功能。

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.

挽清梦 2024-11-25 02:34:47

对于那些寻找 .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;
  }
}

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;
  }
}
贱人配狗天长地久 2024-11-25 02:34:47

我的解决方案遵循 [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
            ));
    }
}

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
            ));
    }
}
花期渐远 2024-11-25 02:34:46

我认为 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()
{
   
}

另请参阅:<一个href="https://web.archive.org/web/20190111075926/http://helios.ca/2009/05/27/aspnet-mvc-action-filter-ajax-only-attribute/" rel="nofollow noreferrer">ASP.NET MVC Action Filter – Ajax Only Attribute 用于实现此目的的另一种方式

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文