Asp.net mvc SimpleMembership密码重置超链接401重定向,即使使用AllowAnonymous
我正试图将MVC4应用程序从ASP.NET成员身份迁移到新的SimpleMembership,但遇到了密码重置问题。在我的登录视图中,我有一个“忘记密码”超链接,该超链接将AJAX发布到发送带有重置密码超链接的电子邮件的操作(大致基于): 我也尝试过删除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
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>