在使用Identity框架進行認證的系統中,我分別使用以下Model,Controller操作和View來實現密碼更改功能(我看到很多文章用於瞭解如何重置密碼,但不知道如何更改密碼儘管當前一個是已知的):ASP.NET MVC爲什麼不從視圖中調用這個帖子操作?
型號:
public class ChangePasswordBindingModel
{
[Required]
[DataType(DataType.Password)]
public string OldPassword { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
[Required]
[DataType(DataType.Password)]
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
控制器動作在AccountController.cs
:
[HttpPost]
public async Task<ActionResult> ChangePassword(ChangePasswordBindingModel loginChange)
{
IdentityResult fffx = await UserManager.ChangePasswordAsync("userId", loginChange.OldPassword, loginChange.NewPassword);
return View("Index");
}
信息查看更改密碼的形式,稱爲ChangePassword.cshtml
:
@model IdentityDevelopment.Models.ChangePasswordBindingModel
@{ ViewBag.Title = "ChangePassword";}
<h2>Change Password</h2>
@using (Html.BeginForm("ChangePassword","Account", FormMethod.Post))
{
//@Html.AntiForgeryToken();
<input type="hidden" name="returnUrl" value="@ViewBag.returnUrl" />
<div class="form-group">
<label>Current Password</label>
@Html.PasswordFor(x => x.OldPassword, new { @class = "form-control" })
</div>
<div class="form-group">
<label>New Password</label>
@Html.PasswordFor(x => x.NewPassword, new { @class = "form-control" })
</div>
<div class="form-group">
<label>Re-enter New Password</label>
@Html.PasswordFor(x => x.ConfirmPassword, new { @class = "form-control" })
</div>
<button class="btn btn-primary" type="submit">Save</button>
}
爲什麼要點擊「保存」按鈕,在表格上沒有調用後的操作方法?
EDIT 1:
我包括爲登錄在控制器方法中,在一個場景中導致ChangePassword形式出現。也許這裏有什麼是一個問題?
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginModel details, string returnUrl)
{
if (ModelState.IsValid)
{
AppUser user = await UserManager.FindAsync(details.Name,
details.Password);
if (user == null)
{
ModelState.AddModelError("", "Invalid name or password.");
}
else
{
//Check if this is initial login of user, force password change if so
PasswordChangeChecker PassCheck = new PasswordChangeChecker();
string userId = user.Id.ToString();
bool proceed = PassCheck.IsPasswordChangedFromInitial(userId);
if (proceed)
{
ClaimsIdentity ident = await UserManager.CreateIdentityAsync(user,
DefaultAuthenticationTypes.ApplicationCookie);
ident.AddClaims(LocationClaimsProvider.GetClaims(ident));
ident.AddClaims(ClaimsRoles.CreateRolesFromClaims(ident));
AuthManager.SignOut();
AuthManager.SignIn(new AuthenticationProperties
{
IsPersistent = false
}, ident);
//persist login into db
Loginobject login = new Loginobject();
login.Username = user.UserName;
login.SessionId = HttpContext.Session.SessionID;
Session["sessionid"] = HttpContext.Session.SessionID;
login.Date = DateTime.Now;
SQLLoginrecord sqlLogin = new SQLLoginrecord();
sqlLogin.PutOrPostLogin(login);
TempData["LoginMsg"] = "Any existing sessions are now deactivated.";
return Redirect(returnUrl);
}
else
{
return View("ChangePassword", new ChangePasswordBindingModel());
}
}
}
ViewBag.returnUrl = returnUrl;
return View(details);
}
編輯2:
它看起來像問題的原因是一個全球性的自定義授權過濾器(感謝您的評論stephen.vakil)[AuthorizeSingleLogin]
,我已經把超過AccountController.cs
AuthorizeSingleLogin.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace IdentityDevelopment.Infrastructure
{
public class AuthorizeSingleLogin : AuthorizeAttribute
{
private AppIdentityDbContext db = new AppIdentityDbContext();
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
bool isAuthorized = base.AuthorizeCore(httpContext);
string user = httpContext.User.Identity.Name;
string access = httpContext.Session.SessionID;
if (String.IsNullOrEmpty(user) || String.IsNullOrEmpty(access))
{
return isAuthorized;
}
SQLLoginrecord sqlLogin = new SQLLoginrecord();
return sqlLogin.IsLoggedIn(user, access);
}
}
}
個
SQLLoginrecord.cs
using IdentityDevelopment.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
using static IdentityDevelopment.Models.Loginobject;
namespace IdentityDevelopment.Infrastructure
{
public class SQLLoginrecord
{
private LoginobjectDBContext db = new LoginobjectDBContext();
private bool PriorSessionActive = false;
public void PutOrPostLogin(Loginobject login)
{
var logins = db.Loginobjects.Where(l => l.Username == login.Username);
if (logins.Any())
{
Loginobject tempLogin = logins.First();
tempLogin.SessionId = login.SessionId;
tempLogin.Date = login.Date;
db.Entry(tempLogin).State = EntityState.Modified;
PriorSessionActive = true;
}
else
{
db.Loginobjects.Add(login);
}
db.SaveChanges();
}
public bool IsLoggedIn(string user, string session)
{
var logins = db.Loginobjects.Where(l => l.Username == user && l.SessionId == session);
if (logins.Any())
{
return true;
}
else
{
return false;
}
}
public bool PriorSessionUpdated()
{
return this.PriorSessionActive;
}
}
}
謝謝。
那麼,單擊按鈕時會發生什麼?你調試過了嗎? –
你的代碼看起來很好。你有任何攔截提交按鈕的js代碼。 – Shyju
@BviLLe_Kid是的,我已經通過在控制器中的post方法中放置一個斷點來進行調試。當我點擊按鈕時,我被重定向到索引頁面,但這不是因爲在這個post方法中調用了Index,而是來自其他地方。 – ITWorker