1
我目前正在練習ASP.NET身份3.0在MVC 5 - 後面幾個教程,並創建了一個MVC項目,我管理以下目前爲止:管理自定義用戶屬性在ASP.NET身份3在MVC 5
- 添加在註冊頁面自定義屬性 從字符串轉換
- 用戶ID爲int
- 遷移和修改連接字符串使用SQL服務器
- 顯示自定義屬性,在管理帳戶頁面
接下來我想讓用戶在管理帳戶頁面上編輯他/她自己的自定義屬性,但我現在很困惑 - 任何人都可以請告訴我我該如何從這裏開始?
UPDATE:通過參照下面提供阿爾奇爾的例子,我已經更新了我的代碼如下所示管理自定義屬性:
ManageController.cs
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security;
using IdentityMVC.Models;
namespace IdentityMVC.Controllers
{
[Authorize]
public class ManageController : Controller
{
ApplicationDbContext db = new ApplicationDbContext();
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
public ManageController()
{
}
public ManageController(ApplicationUserManager userManager, ApplicationSignInManager signInManager)
{
UserManager = userManager;
SignInManager = signInManager;
}
public ApplicationSignInManager SignInManager
{
get
{
return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
}
private set
{
_signInManager = value;
}
}
public ApplicationUserManager UserManager
{
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
private set
{
_userManager = value;
}
}
//
// GET: /Manage/Index
public async Task<ActionResult> Index(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
: message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set."
: message == ManageMessageId.Error ? "An error has occurred."
: message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added."
: message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
: "";
var userId = User.Identity.GetUserId<int>();
var user = UserManager.FindById(userId);
var model = new IndexViewModel
{
HasPassword = HasPassword(),
PhoneNumber = await UserManager.GetPhoneNumberAsync(userId),
TwoFactor = await UserManager.GetTwoFactorEnabledAsync(userId),
Logins = await UserManager.GetLoginsAsync(userId),
Email = await UserManager.GetEmailAsync(userId),
Surname = user.Surname,
GivenName = user.GivenName,
Honors = user.Honors,
Address1 = user.Address1,
Address2 = user.Address2,
City = user.City,
State = user.State,
Postal = user.Postal,
Country = user.Country,
PSANo = user.PSANo,
Id = user.Id,
BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(User.Identity.GetUserId())
};
return View(model);
}
//
// GET: /User/Edit/1
public async Task<ActionResult> Edit()
{
var myUserId = User.Identity.GetUserId();
int myUserIdint = Convert.ToInt32(myUserId);
var myUser = db.Users.FirstOrDefault(x => x.Id == myUserIdint);
if (myUserId == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user = await UserManager.FindByIdAsync(myUserIdint);
if (user == null)
{
return HttpNotFound();
}
var userRoles = await UserManager.GetRolesAsync(user.Id);
return View(new EditUserViewModel()
{
Id = user.Id,
Surname = user.Surname,
GivenName = user.GivenName,
Honors = user.Honors,
Address1 = user.Address1,
Address2 = user.Address2,
City = user.City,
State = user.State,
Postal = user.Postal,
Country = user.Country,
PSANo = user.PSANo,
});
}
//
// POST: /User/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Surname,GivenName,Honors,Address1,Address2,City,State,Postal,Country,PSANo")] EditUserViewModel editUser)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId<int>());
if (user == null)
{
return HttpNotFound();
}
user.Surname = editUser.Surname;
user.GivenName = editUser.GivenName;
user.Honors = editUser.Honors;
user.Address1 = editUser.Address1;
user.Address2 = editUser.Address2;
user.City = editUser.City;
user.State = editUser.State;
user.Postal = editUser.Postal;
user.Country = editUser.Country;
user.PSANo = editUser.PSANo;
var userRoles = await UserManager.GetRolesAsync(user.Id);
var result = await UserManager.AddToRolesAsync(user.Id);
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
return View();
}
result = await UserManager.RemoveFromRolesAsync(user.Id, userRoles.Except(userRoles).ToArray<string>());
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
return View();
}
return RedirectToAction("Index");
}
ModelState.AddModelError("", "Something failed.");
return View();
}
//
// POST: /Manage/RemoveLogin
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> RemoveLogin(string loginProvider, string providerKey)
{
ManageMessageId? message;
var result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId<int>(), new UserLoginInfo(loginProvider, providerKey));
if (result.Succeeded)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId<int>());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
message = ManageMessageId.RemoveLoginSuccess;
}
else
{
message = ManageMessageId.Error;
}
return RedirectToAction("ManageLogins", new { Message = message });
}
//
// GET: /Manage/AddPhoneNumber
public ActionResult AddPhoneNumber()
{
return View();
}
//
// GET: /Manage/ChangePassword
public ActionResult ChangePassword()
{
return View();
}
//
// POST: /Manage/ChangePassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ChangePassword(ChangePasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId<int>(), model.OldPassword, model.NewPassword);
if (result.Succeeded)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId<int>());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", new { Message = ManageMessageId.ChangePasswordSuccess });
}
AddErrors(result);
return View(model);
}
//
// GET: /Manage/SetPassword
public ActionResult SetPassword()
{
return View();
}
//
// POST: /Manage/SetPassword
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> SetPassword(SetPasswordViewModel model)
{
if (ModelState.IsValid)
{
var result = await UserManager.AddPasswordAsync(User.Identity.GetUserId<int>(), model.NewPassword);
if (result.Succeeded)
{
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId<int>());
if (user != null)
{
await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
}
return RedirectToAction("Index", new { Message = ManageMessageId.SetPasswordSuccess });
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
//
// GET: /Manage/ManageLogins
public async Task<ActionResult> ManageLogins(ManageMessageId? message)
{
ViewBag.StatusMessage =
message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
: message == ManageMessageId.Error ? "An error has occurred."
: "";
var user = await UserManager.FindByIdAsync(User.Identity.GetUserId<int>());
if (user == null)
{
return View("Error");
}
var userLogins = await UserManager.GetLoginsAsync(User.Identity.GetUserId<int>());
var otherLogins = AuthenticationManager.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => auth.AuthenticationType != ul.LoginProvider)).ToList();
ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1;
return View(new ManageLoginsViewModel
{
CurrentLogins = userLogins,
OtherLogins = otherLogins
});
}
//
// POST: /Manage/LinkLogin
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LinkLogin(string provider)
{
// Request a redirect to the external login provider to link a login for the current user
return new AccountController.ChallengeResult(provider, Url.Action("LinkLoginCallback", "Manage"), User.Identity.GetUserId());
}
//
// GET: /Manage/LinkLoginCallback
public async Task<ActionResult> LinkLoginCallback()
{
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());
if (loginInfo == null)
{
return RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
}
var result = await UserManager.AddLoginAsync(User.Identity.GetUserId<int>(), loginInfo.Login);
return result.Succeeded ? RedirectToAction("ManageLogins") : RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error });
}
protected override void Dispose(bool disposing)
{
if (disposing && _userManager != null)
{
_userManager.Dispose();
_userManager = null;
}
base.Dispose(disposing);
}
#region Helpers
// Used for XSRF protection when adding external logins
private const string XsrfKey = "XsrfId";
private IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
private void AddErrors(IdentityResult result)
{
foreach (var error in result.Errors)
{
ModelState.AddModelError("", error);
}
}
private bool HasPassword()
{
var user = UserManager.FindById(User.Identity.GetUserId<int>());
if (user != null)
{
return user.PasswordHash != null;
}
return false;
}
private bool HasPhoneNumber()
{
var user = UserManager.FindById(User.Identity.GetUserId<int>());
if (user != null)
{
return user.PhoneNumber != null;
}
return false;
}
public enum ManageMessageId
{
AddPhoneSuccess,
ChangePasswordSuccess,
SetTwoFactorSuccess,
SetPasswordSuccess,
RemoveLoginSuccess,
RemovePhoneSuccess,
Error
}
#endregion
}
}
ManageViewModels.cs
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNet.Identity;
using Microsoft.Owin.Security;
namespace IdentityMVC.Models
{
public class IndexViewModel
{
public bool HasPassword { get; set; }
public IList<UserLoginInfo> Logins { get; set; }
public string PhoneNumber { get; set; }
public bool TwoFactor { get; set; }
public bool BrowserRemembered { get; set; }
public int Id { get; set; }
public string Email { get; set; }
public string Surname { get; set; }
public string GivenName { get; set; }
public string Honors { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Postal { get; set; }
public string Country { get; set; }
public string PSANo { get; set; }
}
public class EditUserViewModel
{
public int Id;
[Required]
[Display(Name = "Surname/Family Name*")]
public string Surname { get; set; }
[Required]
[Display(Name = "Given Name")]
public string GivenName { get; set; }
[Display(Name = "Honors")]
public string Honors { get; set; }
[Required]
[Display(Name = "Address Line 1")]
public string Address1 { get; set; }
[Display(Name = "Address Line 2")]
public string Address2 { get; set; }
[Required]
[Display(Name = "City")]
public string City { get; set; }
[Required]
[Display(Name = "State")]
public string State { get; set; }
[Required]
[Display(Name = "Postal")]
public string Postal { get; set; }
[Required]
[Display(Name = "Country")]
public string Country { get; set; }
[Display(Name = "PSA Membership No. (if applicable)")]
public string PSANo { get; set; }
}
public class ManageLoginsViewModel
{
public IList<UserLoginInfo> CurrentLogins { get; set; }
public IList<AuthenticationDescription> OtherLogins { get; set; }
}
public class FactorViewModel
{
public string Purpose { get; set; }
}
public class SetPasswordViewModel
{
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} 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 ChangePasswordViewModel
{
[Required]
[DataType(DataType.Password)]
[Display(Name = "Current password")]
public string OldPassword { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} 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 AddPhoneNumberViewModel
{
[Required]
[Phone]
[Display(Name = "Phone Number")]
public string Number { get; set; }
}
public class VerifyPhoneNumberViewModel
{
[Required]
[Display(Name = "Code")]
public string Code { get; set; }
[Required]
[Phone]
[Display(Name = "Phone Number")]
public string PhoneNumber { get; set; }
}
public class ConfigureTwoFactorViewModel
{
public string SelectedProvider { get; set; }
public ICollection<System.Web.Mvc.SelectListItem> Providers { get; set; }
}
}
查看\ Manag Ë\ Edit.cshtml
@model IdentityMVC.Models.EditUserViewModel
@{
ViewBag.Title = "Edit";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Edit My Profile</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.Id)
<div class="form-group">
@Html.LabelFor(model => model.Surname, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Surname, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Surname, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.GivenName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.GivenName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.GivenName, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Honors, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Honors, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Honors, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Address1, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Address1, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Address1, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Address2, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Address2, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Address2, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.City, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.City, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.City, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.State, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.State, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.State, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Postal, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Postal, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Postal, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Country, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Country, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Country, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.PSANo, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.PSANo, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.PSANo, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to Profile", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
嗨@ArchilLabadze,我已經試過你的例子,它修改到我的項目,很順利的編輯頁面首先,當我點擊「保存更改」,然後就不停地嘗試重定向到編輯頁面本身,而是與404錯誤。我試過'返回RedirectToAction(「索引」);'在我的控制器處理後,但它仍然是一樣的。你會如此善良地告訴我我做了什麼,可能會導致這樣的錯誤嗎? – Eva
嗨@ArchilLabadze,我找到了我以前的錯誤的解決方案,它似乎是這些導致它: var user = await UserManager.FindByIdAsync(editUser.Id); if(user == null) { return HttpNotFound(); } 我改變了這個: var user = await UserManager.FindByIdAsync(editUser.Id); 到 VAR用戶=等待UserManager.FindByIdAsync(User.Identity.GetUserId()); 一切都很好。感謝您的幫助!。 –
Eva
如果我可以隨時幫助你,歡迎@Eva。 –