Asp.net mvc SimpleMembership密码重置超链接401重定向,即使使用AllowAnonymous

Asp.net mvc SimpleMembership密码重置超链接401重定向,即使使用AllowAnonymous,asp.net-mvc,asp.net-mvc-4,asp.net-mvc-areas,simplemembership,Asp.net Mvc,Asp.net Mvc 4,Asp.net Mvc Areas,Simplemembership,我正试图将MVC4应用程序从ASP.NET成员身份迁移到新的SimpleMembership,但遇到了密码重置问题。在我的登录视图中,我有一个“忘记密码”超链接,该超链接将AJAX发布到发送带有重置密码超链接的电子邮件的操作(大致基于): 我也尝试过删除HttpPost属性,但这也会产生一个401。我错过了什么 更新 感谢Steve的评论,我完全限定了HttpPost属性,现在我意识到它正在尝试将内容发布到一个区域,而不是直接发布到根帐户控制器。使用时,我看到一个未找到资源错误: Matched

我正试图将MVC4应用程序从ASP.NET成员身份迁移到新的SimpleMembership,但遇到了密码重置问题。在我的登录视图中,我有一个“忘记密码”超链接,该超链接将AJAX发布到发送带有重置密码超链接的电子邮件的操作(大致基于):

我也尝试过删除
HttpPost
属性,但这也会产生一个401。我错过了什么

更新
感谢Steve的评论,我完全限定了
HttpPost
属性,现在我意识到它正在尝试将内容发布到一个区域,而不是直接发布到根
帐户
控制器。使用时,我看到一个未找到资源错误:

Matched Route: {controller}/{action}/{id}
Generated URL: /SiteRoot/Reports/Account/ResetPassword?un=whatever&rt=removedForSecurity using the route "Reports/{controller}/{action}/{id}"
请注意,它正在查看
报告
区域。因此,我在
ForgotPassword
操作中更改了锚定标记结构,在route values对象中添加了
区域
规范,如下所示:

var resetLink = "<a href='" + Url.Action("ResetPassword", "Account", new {un = userName, rt = token, Area = ""}, "http") + "'>Reset Password</a>";
更新4
我尝试向Account controller添加另一个操作方法,从而生成“hello world”样式的视图。当然,添加了
[AllowAnonymous]
属性。此方法也会导致401重定向到登录。

非常确定
Area=“”
应该是
Area=“”

我认为您的设置方式没有任何问题。这里肯定还有别的事情。检查您的_Layout.cshmtl文件,并确保您没有任何对可能导致401错误的其他操作的调用


此人也有类似的问题:

有两个AllowAnonYousAttribute类。您确定使用的是
System.Web.Mvc
中的而不是
System.Web.Http
?@Steve-IntelliSense似乎认为它是正确的(
System.Web.Mvc
)。我尝试在属性
[System.Web.Mvc.HttpPost]
中完全限定它,但它得到了一个“未找到资源”错误。我会在一分钟后发布一个更新。而且,看起来你只是在创建一个链接并通过电子邮件发送它。是什么让你认为你应该使用
[HttpPost]
而不是
[HttpGet]
?此外,除非您是匿名的,否则使用
var
通常是不好的做法types@Steve-除非声明匿名类型,否则我不同意使用
var
是不好的做法,尽管如果您提供源代码,我很容易被说服。我只是澄清了您不能将其用于HttpPost。我删除了HttpPost,使用新的链接结构(指定
area=“”
,小写a),我得到了与原来相同的结果:401重定向。我已经清除了所有浏览器中的缓存。这太令人烦恼了!谢谢你的持续帮助。@AJ我不知道,我只是在黑暗中拍摄。天哪,你说得对!我完全忘记了在我的布局文件中有一个
RenderAction
调用,它在站点的每个页面上都会生成一个侧栏菜单。我向该控制器添加了
[AllowAnonymous]
,现在它可以工作了。非常感谢。我会更改它,使其在未经验证时不呈现菜单(或至少部分菜单),但这与我在应用程序中遇到的问题相同。上下文信息或某种伪MVC调用堆栈(什么控制器、操作和/或视图)在MVC应用程序中非常有用。
Matched Route: {controller}/{action}/{id}
Generated URL: /SiteRoot/Reports/Account/ResetPassword?un=whatever&rt=removedForSecurity using the route "Reports/{controller}/{action}/{id}"
var resetLink = "<a href='" + Url.Action("ResetPassword", "Account", new {un = userName, rt = token, Area = ""}, "http") + "'>Reset Password</a>";
@model Whatever.Web.Models.ResetPasswordViewModel
@{
    ViewBag.Title = "Reset Password";
}
@using (Html.BeginForm())
{
    <fieldset>
        <legend>Reset Password</legend>
        <table>
            <tr>
                <td>User name:</td>
                <td>@Html.TextBoxFor(m => m.UserName, new { @class="disabled-textbox", @readonly="readonly", autocomplete="off" })</td>
                <td></td>
            </tr>
            <tr>
                <td>New Password:</td>
                <td>@Html.PasswordFor(m => m.NewPassword, new { id = "resetPasswordNewPassword" })</td>
                <td></td>
            </tr>
            <tr>
                <td>Confirm New Password:</td>
                <td>@Html.Password("resetPasswordConfirmPassword", "", new { id = "resetPasswordConfirmPassword"})</td>
                <td>
                    <div id="passwordsMatch"></div>
                </td>
            </tr>
        </table>
        <input type="submit" id="submitButton" value="Submit" disabled="disabled"/>
        <div id="resetPasswordResultDiv"></div>
    </fieldset>
}
<script type="text/javascript">
    $(document).ready(function() {
        $("#resetPasswordNewPassword, #resetPasswordConfirmPassword").keyup(function() {
            if ($("#resetPasswordNewPassword").val().length > 0 && $("#resetPasswordConfirmPassword").val().length > 0 && $("#resetPasswordNewPassword").val() != $("#resetPasswordConfirmPassword").val()) {
                if ($("#resetPasswordNewPassword").val() != $("#resetPasswordConfirmPassword").val()) {
                    $("#passwordsMatch").html('<span style="color: red; font-weight: bold;>Passwords do not match</span>');
                    $("#submitButton").attr('disabled', true);
                } else {
                    $("#submitButton").removeAttr('disabled');
                }
            } else {
                $("#passwordsMatch").html('');
                $("#submitButton").attr('disabled', true);
            }
        });
    });
</script>