我使用开箱即用的 MVC 4 的简单成员资格。我对网站做了很多更改,现在我要回去清理,我发现我不能再更改我的密码了。我必须蒙上眼睛,因为我认为这应该很容易解决,但我只花了 2 天时间解决这个问题。
我不断收到此错误“索引(从零开始)必须大于或等于零且小于参数列表的大小。” 当它与_ChangePasswordPartial.cshtml 中的@Html.PasswordFor(model => model.NewPassword)一致时。我已经包含了模型、控制器和视图。我知道答案一定很简单,但是谁能告诉我如何纠正这个错误?
模型:
public class LocalPasswordModel
{
[Required]
[DataType(DataType.Password)]
[Display(Name = "Current password")]
public string OldPassword { get; set; }
[Required]
[StringLength(100, ErrorMessage = "Must be at least {6} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
帐户控制器:
public class AccountController : Controller
{
private _GlobalClasses _globalClasses = new _GlobalClasses();
private string pageName;
// GET: /Account/Login
[AllowAnonymous]
//[RequireHttps]
public ActionResult Login(string returnUrl)
{
ViewBag.pageName = "Login";
var multiModels = _globalClasses.Standard(pageName);
return View();
}
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
//[RequireHttps]
[ValidateAntiForgeryToken]
public ActionResult Login(MultiModels model, string returnUrl)
{
pageName = "Login";
var multiModels = _globalClasses.Standard(pageName);
bool trueOrFalse = _globalClasses.Viewed();
ViewBag.Seen = trueOrFalse;
UpdateModel(model.LoginModel);
if (ModelState.IsValid && WebSecurity.Login(model.LoginModel.UserName, model.LoginModel.Password, persistCookie: model.LoginModel.RememberMe))
{
return RedirectToLocal(returnUrl);
}
// If we got this far, something failed, redisplay form
//multiModels.LoginModel = model;
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(multiModels);
}
// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
WebSecurity.Logout();
return RedirectToAction("Index", "Home");
}
//
// GET: /Account/Register
[Authorize(Roles="Admin")]
public ActionResult Register()
{
return View();
}
// POST: /Account/Register
[HttpPost]
[Authorize(Roles = "Admin")]
[ValidateAntiForgeryToken]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
WebSecurity.Login(model.UserName, model.Password);
return RedirectToAction("Index", "Home");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
// POST: /Account/Disassociate
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Disassociate(string provider, string providerUserId)
{
string ownerAccount = OAuthWebSecurity.GetUserName(provider, providerUserId);
ManageMessageId? message = null;
// Only disassociate the account if the currently logged in user is the owner
if (ownerAccount == User.Identity.Name)
{
// Use a transaction to prevent the user from deleting their last login credential
using (var scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.Serializable }))
{
bool hasLocalAccount = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
if (hasLocalAccount || OAuthWebSecurity.GetAccountsFromUserName(User.Identity.Name).Count > 1)
{
OAuthWebSecurity.DeleteAccount(provider, providerUserId);
scope.Complete();
message = ManageMessageId.RemoveLoginSuccess;
}
}
}
return RedirectToAction("Manage", new { Message = message });
}
// GET: /Account/Manage
public ActionResult Manage(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
: message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
: "";
ViewBag.HasLocalPassword = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
ViewBag.ReturnUrl = Url.Action("Manage");
return View();
}
// POST: /Account/Manage
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Manage(LocalPasswordModel model)
{
bool hasLocalAccount = OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
ViewBag.HasLocalPassword = hasLocalAccount;
ViewBag.ReturnUrl = Url.Action("Manage");
if (hasLocalAccount)
{
if (ModelState.IsValid)
{
// ChangePassword will throw an exception rather than return false in certain failure scenarios.
bool changePasswordSucceeded;
try
{
changePasswordSucceeded = WebSecurity.ChangePassword(User.Identity.Name, model.OldPassword, model.NewPassword);
}
catch (Exception)
{
changePasswordSucceeded = false;
}
if (changePasswordSucceeded)
{
return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
}
else
{
ModelState.AddModelError("", "The current password is incorrect or the new password is invalid.");
}
}
}
else
{
// User does not have a local password so remove any validation errors caused by a missing
// OldPassword field
ModelState state = ModelState["OldPassword"];
if (state != null)
{
state.Errors.Clear();
}
if (ModelState.IsValid)
{
try
{
WebSecurity.CreateAccount(User.Identity.Name, model.NewPassword);
return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
}
catch (Exception e)
{
ModelState.AddModelError("", e);
}
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
// POST: /Account/ExternalLogin
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
return new ExternalLoginResult(provider, Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
}
// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
if (!result.IsSuccessful)
{
return RedirectToAction("ExternalLoginFailure");
}
if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false))
{
return RedirectToLocal(returnUrl);
}
if (User.Identity.IsAuthenticated)
{
// If the current user is logged in add the new account
OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name);
return RedirectToLocal(returnUrl);
}
else
{
// User is new, ask for their desired membership name
string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId);
ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
ViewBag.ReturnUrl = returnUrl;
return View("ExternalLoginConfirmation", new RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData });
}
}
// POST: /Account/ExternalLoginConfirmation
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult ExternalLoginConfirmation(RegisterExternalLoginModel model, string returnUrl)
{
string provider = null;
string providerUserId = null;
if (User.Identity.IsAuthenticated || !OAuthWebSecurity.TryDeserializeProviderUserId(model.ExternalLoginData, out provider, out providerUserId))
{
return RedirectToAction("Manage");
}
if (ModelState.IsValid)
{
// Insert a new user into the database
using (var db = new DataBaseContext())
{
UserProfile user = db.UserProfiles.FirstOrDefault(u => u.UserName.ToLower() == model.UserName.ToLower());
// Check if user already exists
if (user == null)
{
// Insert name into the profile table
db.UserProfiles.Add(new UserProfile { UserName = model.UserName });
db.SaveChanges();
OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("UserName", "User name already exists. Please enter a different user name.");
}
}
}
ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(provider).DisplayName;
ViewBag.ReturnUrl = returnUrl;
return View(model);
}
// GET: /Account/ExternalLoginFailure
[AllowAnonymous]
public ActionResult ExternalLoginFailure()
{
return View();
}
[AllowAnonymous]
[ChildActionOnly]
public ActionResult ExternalLoginsList(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return PartialView("_ExternalLoginsListPartial", OAuthWebSecurity.RegisteredClientData);
}
[ChildActionOnly]
public ActionResult RemoveExternalLogins()
{
ICollection<OAuthAccount> accounts = OAuthWebSecurity.GetAccountsFromUserName(User.Identity.Name);
List<ExternalLogin> externalLogins = new List<ExternalLogin>();
foreach (OAuthAccount account in accounts)
{
AuthenticationClientData clientData = OAuthWebSecurity.GetOAuthClientData(account.Provider);
externalLogins.Add(new ExternalLogin
{
Provider = account.Provider,
ProviderDisplayName = clientData.DisplayName,
ProviderUserId = account.ProviderUserId,
});
}
ViewBag.ShowRemoveButton = externalLogins.Count > 1 || OAuthWebSecurity.HasLocalAccount(WebSecurity.GetUserId(User.Identity.Name));
return PartialView("_RemoveExternalLoginsPartial", externalLogins);
}
#region Helpers
private ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
public enum ManageMessageId
{
ChangePasswordSuccess,
SetPasswordSuccess,
RemoveLoginSuccess,
}
internal class ExternalLoginResult : ActionResult
{
public ExternalLoginResult(string provider, string returnUrl)
{
Provider = provider;
ReturnUrl = returnUrl;
}
public string Provider { get; private set; }
public string ReturnUrl { get; private set; }
public override void ExecuteResult(ControllerContext context)
{
OAuthWebSecurity.RequestAuthentication(Provider, ReturnUrl);
}
}
private static string ErrorCodeToString(MembershipCreateStatus createStatus)
{
// See http://go.microsoft.com/fwlink/?LinkID=177550 for
// a full list of status codes.
switch (createStatus)
{
case MembershipCreateStatus.DuplicateUserName:
return "User name already exists. Please enter a different user name.";
case MembershipCreateStatus.DuplicateEmail:
return "A user name for that e-mail address already exists. Please enter a different e-mail address.";
case MembershipCreateStatus.InvalidPassword:
return "The password provided is invalid. Please enter a valid password value.";
case MembershipCreateStatus.InvalidEmail:
return "The e-mail address provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidAnswer:
return "The password retrieval answer provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidQuestion:
return "The password retrieval question provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidUserName:
return "The user name provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.ProviderError:
return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
case MembershipCreateStatus.UserRejected:
return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
default:
return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
}
}
#endregion
}
}
管理.cshtml
@model Spotless_Interiors.Models.LocalPasswordModel
@{
ViewBag.Title = "Manage Account";
}
@section menuLeft {
@Html.Partial("_MenuPartial")
}
<hgroup class="title">
<h1>@ViewBag.Title.</h1>
</hgroup>
<p class="message-success">@ViewBag.StatusMessage</p>
<p>You're logged in as <strong>@User.Identity.Name</strong>.</p>
@if (ViewBag.HasLocalPassword)
{
@Html.Partial("_ChangePasswordPartial", Model)
}
else
{
@Html.Partial("_SetPasswordPartial")
}
<section id="externalLogins">
@Html.Action("RemoveExternalLogins")
<h3>Add an external login</h3>
@Html.Action("ExternalLoginsList", new { ReturnUrl = ViewBag.ReturnUrl })
</section>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
_CHANGEPASSWORDPARTIAL.cshtml
@model Spotless_Interiors.Models.LocalPasswordModel
<h3>Change password</h3>
@using (Html.BeginForm("Manage", "Account")) {
@Html.AntiForgeryToken()
@Html.ValidationSummary()
<fieldset>
<legend>Change Password Form</legend>
<ol>
<li>
@Html.LabelFor(model => model.OldPassword)
@Html.PasswordFor(model => model.OldPassword)
</li>
<li>
@Html.LabelFor(model => model.NewPassword)
@Html.PasswordFor(model => model.NewPassword)
</li>
<li>
@Html.LabelFor(model => model.ConfirmPassword)
@Html.PasswordFor(model => model.ConfirmPassword)
</li>
</ol>
<input type="submit" value="Change password" />
</fieldset>
}