在 MVC 5 的 ASP.NET Identity 3 管理自定义用户属性

Manage Custom User Properties at ASP.NET Identity 3 in MVC 5

我目前正在练习 ASP.NET MVC 5 中的 Identity 3.0 - 遵循了一些教程并创建了一个 MVC 项目,到目前为止我已经管理了以下内容:

  1. 在注册页面添加了自定义属性
  2. 已将用户 ID 从字符串转换为整数
  3. 迁移和修改连接字符串以使用 SQL 服务器
  4. 在“管理帐户”页面显示自定义属性

接下来我想让用户能够在“管理帐户”页面上编辑 his/her 自己的自定义属性,但我现在很困惑 - 谁能告诉我如何从这里开始?

更新:通过参考下面提供的 Archil 示例,我更新了我的代码,如下所示以管理自定义属性:

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; }
    }
}

View\Manage\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")
}

美好的一天,我已经做到了,它对我有用: 我的编辑用户模型:

public class ManageEditUserViewModel
{
    public string Id { get; set; }

    [Required]
    [Display(Name = "FirstName")]
    public string FirstName { get; set; }
    [Required]
    [Display(Name = "LastName")]
    public string LastName { get; set; }

    public string DisplayName { get; set; }

    [Required(AllowEmptyStrings = false)]
    [Display(Name = "UserName")]
    public string UserName { get; set; }

    [Required(AllowEmptyStrings = false)]
    [Display(Name = "Email")]
    [EmailAddress]
    public string Email { get; set; }

    [Display(Name = "BirthDate")]
    [DataType(DataType.Date), DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
    public DateTime BirthDate { get; set; }
    [NotMapped]
    public int Day { get; set; }
    [NotMapped]
    public int Month { get; set; }
    [NotMapped]
    public int Year { get; set; }
    public int Gender { get; set; }
}

这是我的控制器(GET 和 Post):

//
    // GET: /User/Edit/1
    public async Task<ActionResult> Edit()
    {
        var myUserId = User.Identity.GetUserId();
        var myUser = db.Users.FirstOrDefault(x => x.Id == myUserId);

        if (myUserId == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        var user = await UserManager.FindByIdAsync(myUserId);

        if (user == null)
        {
            return HttpNotFound();
        }

        var userRoles = await UserManager.GetRolesAsync(user.Id);

        return View(new ManageEditUserViewModel()
        {
            Id = user.Id,
            UserName = user.UserName,
            Email = user.Email,
            FirstName = user.FirstName,
            LastName = user.LastName,
            DisplayName = user.FirstName + " " + user.LastName,
            Gender = user.Gender,
            BirthDate = user.BirthDate,
            Year = user.BirthDate.Year,
            Month = user.BirthDate.Month,
            Day = user.BirthDate.Day,

        });
    }

    //
    // POST: /User/Edit/5
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Edit([Bind(Include = "FirstName,LastName,DisplayName,Gender,UserName,Email,Id,Year,Month,Day")] ManageEditUserViewModel editUser)
    {
        DateTime dob = new DateTime(editUser.Year, editUser.Month, editUser.Day);
        if (ModelState.IsValid)
        {
            var user = await UserManager.FindByIdAsync(editUser.Id);
            if (user == null)
            {
                return HttpNotFound();
            }

            user.UserName = editUser.UserName;
            user.Email = editUser.Email;
            user.FirstName = editUser.FirstName;
            user.LastName = editUser.LastName;
            user.DisplayName = editUser.FirstName + "<span> </span>" + editUser.LastName;
            user.Gender = editUser.Gender;
            user.BirthDate = dob;

            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();
            }

            var name = user.DisplayName;
            var message = editsuccess.Content;
            context.Clients.All.addNewMessageToPage(name, message);
            return RedirectToAction("MyProfile");
        }
        ModelState.AddModelError("", "Something failed.");
        return View();
    }

最后查看:

@model MyApp.Models.ManageEditUserViewModel
@{
ViewBag.Title = "EditUser";
 }
 <div class="page-header">
<h3 class="text-center text-uppercase">EditUser</h3>
</div>
<div class="row">
<div class="col-sm-3">
</div>
<div class="col-sm-6">
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()

        <div class="form-horizontal">
            @Html.ValidationSummary(true)
            @Html.HiddenFor(model => model.Id)
            @Html.HiddenFor(model => model.UserName)
            @Html.HiddenFor(model => model.Email)

            <div class="form-group">
                @Html.LabelFor(model => model.FirstName, new { @class = "control-label col-md-2" })
                <div class="col-md-6">
                    @Html.TextBoxFor(m => m.FirstName, new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.FirstName)
                </div>
            </div>

            <div class="form-group">
                @Html.LabelFor(model => model.LastName, new { @class = "control-label col-md-2" })
                <div class="col-md-6">
                    @Html.TextBoxFor(m => m.LastName, new { @class = "form-control" })
                    @Html.ValidationMessageFor(model => model.LastName)
                </div>
            </div>


            <div class="form-group">
                <div class="col-lg-offset-2 col-md-6">
                    <strong>@Html.LabelFor(model => model.BirthDate) </strong>
                </div>
            </div>
            <div class="form-group">

                <div class="col-lg-offset-2 col-md-6">
                    @Html.DropDownListFor(model => model.Day, Enumerable.Range(1, 31).Select(i => new SelectListItem { Value = i.ToString(), Text = i.ToString() }), "Day")
                    @Html.DropDownListFor(model => model.Month, Enumerable.Range(1, 12).Select(i => new SelectListItem { Value = i.ToString(), Text = System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat.GetMonthName(i) }), "Month")
                    @Html.DropDownListFor(model => model.Year, Enumerable.Range(1900, 114).Select(i => new SelectListItem { Value = i.ToString(), Text = i.ToString() }), "Year")
                    @Html.ValidationMessageFor(model => model.BirthDate, "", new { @class = "text-danger" })
                </div>
            </div>
            <div class="form-group">
                <div class="col-lg-offset-2 col-md-6">
                    <label>
                        @Html.RadioButtonFor(x => x.Gender, 1) Male
                    </label>
                    <label>
                        @Html.RadioButtonFor(x => x.Gender, 2) Female
                    </label>
                </div>
            </div>
            <div class="form-group">
                <div class="col-md-offset-2 col-md-7">
                    <input type="submit" value="Save Changes" class="btn    btn-default" /> <span> </span> @Html.ActionLink("Back", "Index", null, new {      @class = "btn btn-default" })
                </div>
            </div>
        </div>
    }
 </div>
 <div class="col-sm-3">

 </div>
 </div>
 @section Scripts {
 @Scripts.Render("~/bundles/jqueryval")
 }

它工作正常你也可以定义你的属性,回家它会帮助你。