登录时Orchard CMS Ajax防伪标记

Bri*_*ehm 10 orchardcms asp.net-mvc-3

我正在构建一个Orchard CMS模块,我正在Orchard 1.3.10网站上进行测试.该模块显示我的一个实体的详细信息视图,我有一个"收藏夹"按钮,我想点击并对控制器操作执行ajax发布,以将实体保存为数据库中的收藏夹.

在视图上我有以下代码:

<div style="padding: 10px;">
    <span data-id="@Model.Id" id="addFavorite" style="cursor: pointer;">
    [Add Favorite]
    </span>
</div>

<script type="text/javascript">
    $("#addFavorite").click(function () {
        alert("here we go...");
        $.ajax({
            type: "post",
            dataType: "",
            url: "/orchardlocal/mymodule/stuff/AddFavorite",
            data: { id: $(this).data("id") },
            success: function (response) {
                alert("it worked");
            }
        });
    });
</script>
Run Code Online (Sandbox Code Playgroud)

我的控制器动作是......

[HttpPost]
public ActionResult AddFavorite(int id)
{
    return View();
}
Run Code Online (Sandbox Code Playgroud)

当我在没有登录Orchard的情况下运行该站点时,此代码的回复就好了.如果我登录并点击添加收藏夹,我会收到此异常...

未提供所需的防伪标记或无效.

用户代码未处理System.Web.Mvc.HttpAntiForgeryException消息=未提供所需的防伪标记或无效.Source = System.Web.WebPages ErrorCode = -2147467259 WebEventCode = 0 StackTrace:System.Web.Helpers.AntiForgery.Validate(HttpContextBase httpContext,String salt)中的System.Web.Helpers.AntiForgeryWorker.Validate(HttpContextBase context,String salt)在System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext> filterContext)的Orchard.Mvc.AntiForgery.AntiForgeryAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext)中的C:\ Code\OrchardDev2\src\Orchard\Mvc\AntiForgery\AntiForgeryAuthorizationFilter.cs:line 37在System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext,IList`1过滤器,ActionDescriptor actionDescriptor)处于System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext,String actionName)InnerException:

登录时为什么会以不同方式处理帖子而不是?

如何提供反伪造令牌以避免这种情况?

谢谢,Brian

Séb*_*SFT 23

默认情况下,ASP.NET MVC不支持生成原始防伪标记.幸运的是,Orchard提供了一种扩展方法.

您可以按原样更改您的ajax调用:

$.ajax({
    type: "post",
    dataType: "",
    url: "/orchardlocal/mymodule/stuff/AddFavorite",
    data: { 
        id: $(this).data("id") },
        __RequestVerificationToken: '@Html.AntiForgeryTokenValueOrchard()'
    },
    success: function (response) {
        alert("it worked");
    }
});
Run Code Online (Sandbox Code Playgroud)

此技术非常有用,因为您不需要在页面上使用现有的FORM.虽然此解决方案仅在从Razor视图呈现javascript时才有效.

如果您的视图中有一个单独的脚本文件,那么仍然有一个解决方案,即将防伪标记保存在从视图声明的javascript变量中,然后从脚本中使用它:

@using(Script.Head()) {
<script type="text/javascript">
//<![CDATA[
    var antiForgeryToken = '@Html.AntiForgeryTokenValueOrchard()';
//]]>
</script>
}
Run Code Online (Sandbox Code Playgroud)

然后从脚本:

data: { 
    id: $(this).data("id") },
    __RequestVerificationToken: antiForgeryToken 
}
Run Code Online (Sandbox Code Playgroud)

如果没有,那么达林提出的解决方案将是他正确的方法.