I'm working in MVC5/WebAPI using ASP.NET Identity, with a custom storage provider for my UserStore, custom ApplicationUser inheriting from IdentityUser, and a pretty expansive configuration in the project (both MVC5 and WebAPI endpoints in the same project).I've been working on the user management/settings controller (ManageController), following the same principles the template projects use; however, with the additional fields I have in my ApplicationUser, it is getting to the point that my view model is starting to be a duplicate of the ApplicationUser class. I wanted someone to take a look at some of my code and let me know if they think the way I'm setting things up currently is appropriate, or if I am cluttering a view model with fields.ManageViewModels.csusing System.Collections.Generic;using System.ComponentModel.DataAnnotations;using Microsoft.AspNet.Identity;using Microsoft.Owin.Security;using System.Security.Claims;namespace Disco.Models{    public class IndexViewModel    {                public string Email { get; set; }                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 string FirstName { get; set; }        public string LastName { get; set; }        public string Picture { get; set; }        public string Handle { 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; }    }}ApplicationUser.csusing System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Microsoft.AspNet.Identity;using System.Security.Claims;using Newtonsoft.Json;namespace Schloss.AspNet.Identity.Neo4j{    public class ApplicationUser : IdentityUser    {        public string FirstName { get; set; }        public string LastName { get; set; }        public DateTimeOffset DateOfBirth { get; set; }        // @ handle / username        public string Handle { get; set; }        public string Picture { get; set; }        public char Gender { get; set; }        public string DeviceId { get; set; } // Most recently used mobile phone ID (iPhone, iPad, Android, etc)        // Address        public string City { get; set; }        public string State { get; set; }        public string ZIPCode { get; set; }        public string County { get; set; }        public string Country { get; set; }        public string Address1 { get; set; }        public string Address2 { get; set; }        public string Address3 { get; set; }        // SignalR        public HashSet<string> ConnectionIds { get; set; } // SignalR connections set (for handling multiple live sessions, propagation of push notifications)        //public static string Labels { get { return User; } }        // Helper Properties        [JsonIgnore]        public String FullName        {            get { return (FirstName +   + LastName).Trim(); } // helper property to format user's full name        }        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)        {            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);            // Add custom user claims here            return userIdentity;        }        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)        {            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType            var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);            // Add custom user claims here            return userIdentity;        }    }}ManageController.cs (just the Index view)//        // 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();            var user = await UserManager.FindByIdAsync(userId);            var model = new IndexViewModel            {                                Email = await UserManager.GetEmailAsync(userId),                                HasPassword = await UserManager.HasPasswordAsync(userId),                PhoneNumber = await UserManager.GetPhoneNumberAsync(userId),                TwoFactor = await UserManager.GetTwoFactorEnabledAsync(userId),                Logins = await UserManager.GetLoginsAsync(userId),                BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(userId),                FirstName = user.FirstName,                LastName = user.LastName,                Picture = user.Picture,                Handle = user.Handle            };            return View(model);        }
ASP.NET View Model / Identity Model
c#;asp.net