I’m in the process of learning MVC with Identity 2 and I’m at the point of taking a sample project and tweaking it to fit a site that I’m trying to convert from WebForms with ASP.Net Membership provider.
What I’m having issues with at the moment is getting my head wrapped around how I get a value from another table to populate a property in a class.
I have a class called AppUser.cs and it inherits from IdentityUser. That is basically mapped to a table named “AspNetUsers” using EntityFramework. I’ve added a couple more properties (First/Last Name) to that table using EF migrations. Now I want to display what Role the user is assigned to and eventually will need to get a list of the available roles and add them to a dropdownlist. I added the RoleName property to my AppUser class but I’m assuming that since that data is not stored in the AspNetUsers table is why I’m getting an error “Invalid column name 'RoleName'”.
How would I populate the Role and/or get a list of available Roles in my AppUser class so I can display it in my View?
public class AppUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string RoleName { get; set; }
}
The model on the view “Index.cshtml” is the AppUser.
#model IEnumerable<AppUser>
This is my ActionResult for my Controller.
public ActionResult Index() {
return View(UserManager.Users);
}
private AppUserManager UserManager {
get {
return HttpContext.GetOwinContext().GetUserManager<AppUserManager>();
}
}
This is the AppUserManager.cs
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using SampleMvcSite.Models;
namespace SampleMvcSite.Infrastructure {
public class AppUserManager : UserManager<AppUser> {
public AppUserManager(IUserStore<AppUser> store)
: base(store) {
}
public static AppUserManager Create(
IdentityFactoryOptions<AppUserManager> options,
IOwinContext context) {
AppIdentityDbContext db = context.Get<AppIdentityDbContext>();
AppUserManager manager = new AppUserManager(new UserStore<AppUser>(db));
manager.PasswordValidator = new CustomPasswordValidator {
RequiredLength = 6,
RequireNonLetterOrDigit = false,
RequireDigit = false,
RequireLowercase = true,
RequireUppercase = true
};
manager.UserValidator = new CustomUserValidator(manager) {
AllowOnlyAlphanumericUserNames = true,
RequireUniqueEmail = true
};
return manager;
}
}
}
UPDATED CODE:
I ended up creating a class called UserEditViewModel and I'm also including the AppRole class which was in the sample project I'm tweaking.
public class UserEditViewModel : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserRole { get; set; }
public IEnumerable<AppRole> AllRoles { get; set; }
}
public class AppRole : IdentityRole {
public AppRole() : base() { }
public AppRole(string name) : base(name) { }
}
Then in my controller I did the following. Keep in mind I'm only going to allow a user to be assigned to one role at a time so theoretically there should only be the one role which is why I only called on the userRoles[0]. Since I added the RoleManager after some sample users I have a couple users that aren't assigned to a Role. I added a check to make sure the Roles had a count and if not I display "User" as their role. I will go back and add code to actually add the user to the "User" role if no roles are found.
List<UserEditViewModel> UserList = new List<UserEditViewModel>();
var users = UserManager.Users;
foreach (AppUser user in users)
{
var userRoles = await UserManager.GetRolesAsync(user.Id);
string roleName = userRoles.Count() == 0 ? "User" : userRoles[0];
UserEditViewModel editUser = new UserEditViewModel();
editUser.UserName = user.UserName;
editUser.FirstName = user.FirstName;
editUser.LastName = user.LastName;
editUser.Email = user.Email;
editUser.UserRole = roleName;
editUser.AllRoles = RoleManager.Roles;
UserList.Add(editUser);
}
return View(UserList);
Here is the View
<div class="form-group">
<label>Role:</label> #Html.DisplayNameFor(model => model.UserRole)
</div>
I would look at ViewModels. It's generally bad practice to update an entity model in your view - especially security related entities. See https://www.stevefenton.co.uk/2013/03/Why-You-Never-Expose-Your-Domain-Model-As-Your-MVC-Model/
With a viewmodel, you could have a property for List<Role> that you populate in your controller and use in your view and another property like RoleId for the user's role.
In the POST you would do something like:
if (ModelState.IsValid)
{
var roleMgr = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(context));
var userMgr = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(context));
var role = roleMgr.FindById(viewmodel.RoleId);
if (role != null) userMgr.AddToRole(viewmodel.UserId, role.Name);
}
VIEW:
<div class="form-group">
#Html.LabelFor(model => model.RoleId)
<div class="col-md-2">
#Html.DropDownListFor(model => model.RoleId, Model.RoleList, htmlAttributes: new { #class = "form-control" })
</div>
<div class="col-md-10 col-md-offset-2">
#Html.ValidationMessageFor(model => model.RoleId, "", new { #class = "text-danger" })
</div>
</div>
Related
I am using .Net Core 2.1 and I want to exclude the users that have the role "Admin" and "SimpleUser" I had followed this example Link
How i can add the where part?
So far i have tried this with no luck:
ViewData["ApplicationUserId"] = new SelectList( _context.Users.Include(u=>u.UserRoles).ThenInclude(u=>u.Role).Where(o=>o.UserRoles!="Admin"), "Id", "Company", products.ApplicationUserId);
ApplicationUserRole Class:
public class ApplicationUserRole : IdentityUserRole<string>
{
public virtual ApplicationUser User { get; set; }
public virtual ApplicationRole Role { get; set; }
}
The message in the attached image suggests that u.UserRoles is not a string, try something like u.UserRoles.All(r=>r.RoleId!="Admin" && r.RoleId!="SimpleUser") in your Where
You will need to check that none of the roles are of "Admin" or "SimpleUser"
ViewData["ApplicationUserId"] = new SelectList( _context.Users.Include(u=>u.UserRoles).ThenInclude(u=>u.Role).Where(o => !o.UserRoles.Any(r => (r.Role == "Admin") || (r.Role == "SimpleUser"))), "Id", "Company", products.ApplicationUserId);
I have a class with two references to the same class. When updating the main class, I may also update the referenced class. When I have two references to the same (modified) object, I get an InvalidOperationException:
Attaching an entity of type 'ns.entity' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
Simple example:
public class Example {
public int OldestFriendId {get; set;}
public int BestFriendId {get; set;}
public virtual Friend Oldest {get; set; }
public virtual Friend Best {get; set; }
}
If while updating Example, I want to update the Middle name of my Oldest/Best friend, it works as long as they aren't the same. But if they are the same, then I get the above exception.
I can't figure out how to get this to work. I've tried setting references to null, saving them independently of the parent class, setting all references in them to null (EF is automatically creating two list of Examples in Friend).
How can I save an object that has changed when there are multiple references to it?
UPDATE: not yet working the way I want, but I have had some progress after removing the list of Examples from Friend. Also, the update is the result of a POST. Still investigating...
As sample code was asked for...this is from a post on a web app, no change was actually made
public ActionResult SaveEdit(int id, [Bind(Include = "OldestFriendId, BestFrinedId, Oldest, Best")] Example example)
{
if (ModelState.IsValid)
{
using (((WindowsIdentity)ControllerContext.HttpContext.User.Identity).Impersonate())
{
using (var _db = new exampleEntities())
{
//example.Best= example.Oldest; // this line would allow the update to work.
//next line is where the exception occurs
_db.Entry(example).State = EntityState.Modified;
_db.SaveChanges();
}
}
}
}
The EditorFor template:
#model Testing.Friend
<div class="col-md-10">
#Html.HiddenFor(model => model.FriendId)
#Html.EditorFor(model => model.FirstName)
#Html.EditorFor(model => model.LastName)
</div>
The Edit view for Example
#model Testing.Example
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Example</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.ExampleId)
<div class="form-group">
#Html.LabelFor(model => model.OldestFriendId, "OldestFriendId", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.HiddenFor(model => model.OldestFriendId)
#Html.EditorFor(model => model.Oldest)
</div>
<div class="form-group">
#Html.LabelFor(model => model.BestFriendId, "BestFriendId", htmlAttributes: new { #class = "control-label col-md-2" })
#Html.HiddenFor(model => model.BestFriendId)
#Html.EditorFor(model=> model.Best)
</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>
}
EDIT
The most likely cause is because when you retrieve the object back, it deserializes the 2 friends as 2 completely different objects (even when they are the same). Same problem as below, but rather than EF deserializing into 2 objects, ASP.NET MVC is doing it.
What you will have to do is something like the following:
Check if the 2 Friend ID's are the same (as ID is the PK). If not continue as normal
If they have the same ID, check if the 2 friend objects are the same.
If they are the same go to step 5.
Combine the changes together, however you want to deal with conflicts.
Set one of the Freinds to the same as the other Friend reference, e.g. Best = Oldest
SaveChanges()
Original Answer
My guess is that this is the classic problem of Include when you are retrieving the data.
When you do
Context.Examples.Include(x => x.Oldest).Include(x => x.Best).ToList()
What is happening is EF will create TWO objects of friend(Oldest and Best), even if they point to the same record. This is a known problem with include.
So when you go to save after update, EF sees them as 2 separate entities with the same key (and data) and complains.
If this is the case you have a couple of options:
Retrieve a list of all Friends for the current example and then the Example without the include
Let EF use LazyLoading and load the Friends when and as you need them.
My solution to the problem was to stop binding the whole object, and bind to the individual objects.
public ActionResult SaveEdit(int id, [Bind(Include = "OldestFriendId, BestFrinedId")] Example example,
Bind(Prefix="Oldest", Include = "FriendId, FirstName, MiddleName, LastName")] Friend oldest,
Bind(Prefix="Best", Include = "FriendId, FirstName, MiddleName, LastName")] Friend best) {
if (ModelState.IsValid)
{
using (((WindowsIdentity)ControllerContext.HttpContext.User.Identity).Impersonate())
{
using (var _db = new exampleEntities())
{
// do whatever processing you want on best and/or oldest
example.BestFriendId = best.FriendId;
example.OldestFriendId = oldest.FriendId;
_db.Entry(example).State = EntityState.Modified;
_db.SaveChanges();
}
}
}
}
EDIT: Replaced with full sample code
This example works for me.
I think is does what you are trying.
using System;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Migrations;
namespace Ef6Test {
public class Program {
public static void Main(string[] args) {
ExecDb1();
}
private static void ExecDb1() {
Database.SetInitializer(new MigrateDatabaseToLatestVersion<Ef6Ctx, Ef6MigConf>());
WhichDb.DbName = "MSAMPLEDB";
WhichDb.ConnType = ConnType.CtxViaDbConn;
var sqlConn = GetSqlConn4DBName(WhichDb.DbName);
var context = new Ef6Ctx(sqlConn);
context.Database.Initialize(true);
Console.WriteLine(WhichDb.DbName, context.Database.Exists() );
AddJunk(context);
}
public static class WhichDb {
public static string DbName { get; set; }
public static string ConnectionName { get; set; }
public static ConnType ConnType { get; set; }
}
public enum ConnType {
CtxViaDbConn,
CtxViaConnectionName
}
private static void AddJunk(DbContext context) {
var friend = new Friend();
friend.Name = "Fred";
friend.Phone = "555-1232424";
context.Set<Friend>().Add(friend);
context.SaveChanges();
// break here and check db content.
var eg = new Example();
eg.Best = friend; // set them equal
eg.Oldest = friend;
friend.Name = "Fredie"; // change the name of the fly
friend.Phone = "555-99999"; // and phone is also different
context.Set<Example>().Add(eg); Add the new example
context.SaveChanges();
// result... 2 records.
// The original friend record should be chnaged
}
public static DbConnection GetSqlConn4DBName(string dbName) {
var sqlConnFact = new SqlConnectionFactory(
"Data Source=localhost; Integrated Security=True; MultipleActiveResultSets=True");
var sqlConn = sqlConnFact.CreateConnection(dbName);
return sqlConn;
}
}
public class MigrationsContextFactory : IDbContextFactory<Ef6Ctx> {
public Ef6Ctx Create() {
switch (Program.WhichDb.ConnType) {
case Program.ConnType.CtxViaDbConn:
var sqlConn = Program.GetSqlConn4DBName(Program.WhichDb.DbName); //
return new Ef6Ctx(sqlConn);
case Program.ConnType.CtxViaConnectionName:
return new Ef6Ctx(Program.WhichDb.ConnectionName);
default:
throw new ArgumentOutOfRangeException();
}
}
}
public class Ef6MigConf : DbMigrationsConfiguration<Ef6Ctx> {
public Ef6MigConf() {
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
}
public class Friend {
public int Id { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
}
public class Example
{
public int Id { get; set; }
public int? BestFriendId { get; set; }
public int? OldestFriendId { get; set; }
public virtual Friend Best { get; set; }
public virtual Friend Oldest { get; set; }
}
public class Ef6Ctx : DbContext {
public Ef6Ctx(DbConnection dbConn) : base(dbConn, true) { }
public Ef6Ctx(string connectionName) : base(connectionName) { }
public DbSet<Friend> Friends { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Example>()
.HasOptional(t=>t.Best)
.WithMany()
.HasForeignKey(x=>x.BestFriendId);
modelBuilder.Entity<Example>()
.HasOptional(t => t.Oldest)
.WithMany()
.HasForeignKey(x => x.OldestFriendId);
}
}
}
Here's what I want to do: I want to set the AspNetUserRole to the new user, right in the Registration page.
Model:
namespace MyProject.Models
{
public enum AccountRole
{
Responder = 10003, Sender= 10002, Admin = 10001
}
...
[Required()]
[Display(Name = "Account role")]
public AccountRole? AccountRole { get; set; }
View:
#Html.LabelFor(model => model.AccountRole, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EnumDropDownListFor(model => model.AccountRole, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.AccountRole, "", new { #class = "text-danger" })
</div>
Registration page result: http://imgur.com/1lHL06L
Controller:
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
//User accountRole to AspNetUserRoles BY JULIUS
var accountRole = model.AccountRole;
await SignInAsync(user, isPersistent: false);
string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
var callbackUrl = Url.Action("ConfirmEmail", "Account",
new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
await UserManager.SendEmailAsync(user.Id,
"Confirm your account", "Please confirm your account by clicking <a href=\""
+ callbackUrl + "\">here</a>");
return RedirectToAction("Index", "Home");
}
else
{
AddErrors(result);
}
}
Please direct your attention to the AccountController.cs Register part.
I have successfully collected the entered the AccountRole Enum from the dropdown:
var accountRole = model.AccountRole;
What I want to do is set accountRole to the AspNetUserRoles table in my Entity Framework generated DefaultConnection
Table: http://i.imgur.com/YBI3NSp.png
How do I solve this in my Controller code?
From what I understand you may want to extend the IdentityUserRole class.
This class represents the relation between a user and his role.
public class AccountRole: IdentityUserRole<TKey>
{
public override TKey RoleId
{
get;
set;
}
public override TKey UserId
{
get;
set;
}
public IdentityUserRole()
{
}
public string somenewproperty(){
get; set;
}
}
Then I believe you will have to override your createUserRole in the userManager or more specific the RoleManager
public class ApplicationRoleManager : RoleManager<IdentityRole> {
//...And so on
}
Check out this link for a full overview of the identity management
What I don't really get is why you would want to do this in the first place.
You could add a new role to the Roles table and tie that role to certain rules and in that case you could just use the built-in RoleManager to assign roles to users.
await userManager.AddToRoleAsync(userId, AccountRole.Admin);
and in this case, your AccountRole will be an Enum
public enum AccountRole {
Admin,
User
}
So to make this work, you will have to add the roles to the database like so:
context.Roles.Add(new IdentityRole("SomeRoleNameHere"));
this is best done in the Seed method;
Then you have your register method:
[Route("Register")]
public async Task<IHttpActionResult> Register(RegisterBindingModel model)
{
//Do the register of the user
//Next:
await UserManager.AddToRoleAsync(userId, AccountRole.Admin);
}
This will add the user to the role of "Admin" if added correctly.
Now if you look in the database, the AspNetUserRoles will have your UserId and RoleId matched to one another.
If you cannot get this to work, you can also make a static class, I did this in a previous project.
It works the same way only the "rolenames" object looks like this:
public static class RoleNames {
public const string Supervisor = "Supervisor";
public const string Administrator = "Administrator";
}
All the other things - like adding them to the DB in the seed method and so on are exactly the same.
And adding it to a user as well:
await userManager.AddToRoleAsync(UserId, RoleNames.Supervisor);
I am trying to add multiple rows of data and pass it to the table in database along with another item to a different table. Below is the struct of the databse:
User Table
userid
name
Movie Table
Movieid
userid
moviename
Cinema Table
Movieid
cinemaid
location
time
The movietable has 1 to many realtionship with the Cinema table. The user table has one I have four different viewmodels associating to them:
UserViewModel
{
public int userid;
public string name;
}
MoviewViewModel
{
public int movieid;
public int userid;
public string moviename;
public List<CinemaViewModel> cinema;
}
CinemaViewModel
{
public int movieid;
public int cinemaid;
public string location;
public string time;
}
UserandMovieViewModel
{
public List<MoviewViewModel> movie;
public UserViewModel user;
}
I am passing the userandmoviewmodel from the controller create to the view and would like to add one entry for user and movie, but would like to add multiple entries to the Cinema database from that single page. it works fine when i add a single entry to cinema. however i would like to have the ability to add multiple entries to cinema table when form is posted. I have tried the tutorial below but that doesnt seem to work for create.
http://ivanz.com/2011/06/16/editing-variable-length-reorderable-collections-in-asp-net-mvc-part-1/
EDIT
The code which give null exception
<ul id="movieEditor" style="list-style-type: none">
#foreach (CinemaViewModel cinemamodel in Model.UserandMovieViewModel.cinema) {
Html.RenderPartial("MovieEntryEditor", cinemamodel);
}
</ul>
<a id="addAnother" href="#">Add another</a>
EDIT2
The create controller code
[httpget]
public ActionResult Create()
{
UserViewModel usermodel = new UserviewModel();
List<MovieViewModel> moviemodel= new List<MovieViewModel>();
UserandMovieViewModel model = new UserandMovieViewmodel{user = usermodel, movie=moviemodel }
return View(model)
}
[httppost]
public ActionResult Create(UserandMovieViewmodel model)
{
IRepository<User> userrep = new ApplicationRepository<User>();
IRepository<Movie> userrep = new ApplicationRepository<Movie>();
IRepository<Cinema> userrep = new ApplicationRepository<Cinema>();
User user = null;
Movie movie = null;
Cinema cinema = null;
UserViewModel usermodel = model.usermodel;
MovieViewModel moviemodel= model.moviemodel;
CinemaViewModel cinemamodel = model.moviemodel.cinema;
if(ModelState.valid)
{
user = new user();
user.name = usermodel.name;
userrep.add(user);
movie = new movie();
movie.userid = user.userid; (gets from database as its autoappend)
movie.moviename = moviemodel.moviename;
movierep.Add(movie);
cinema = new cinema();
cinema.movieid = movie.movieid;
cinema.location = cinemamodel.location;
cinema.time = cinemamodel.time;
cinemarep.Add(cinema);
}
return View(model);
}
I have written the code from memory as i dont currently have it. Please correct any errors you see.
EDIT 3
Partial View
#model Application.ViewModels.CinemaViewModel
<li style="padding-bottom:15px">
<div style="width: 450px; float: left;">
<label class="location">
Location
</label>
<span style="margin-left: 26px;">
#Html.TextBoxFor(model => model.location)
#Html.ValidationMessageFor(model => model.location)
</span>
<span>
#Html.TextBoxFor(model => model.time)
#Html.ValidationMessageFor(model => model.time)
</span>
</div>
I suspect that you have your list as null, so you can try just to new it up in constructor:
public class MoviewViewModel
{
public MoviewViewModel(){
cinema = new List<CinemaViewModel>();
}
public int movieid;
public int userid;
public string moviename;
public List<CinemaViewModel> cinema;
}
public class UserandMovieViewModel
{
public UserandMovieViewModel(){
movie = new List<MoviewViewModel>();
}
public List<MoviewViewModel> movie;
public UserViewModel user;
}
EDIT:
Your view:
<ul id="movieEditor" style="list-style-type: none">
#if(Model.UserandMovieViewModel.cinema.Any())
{
foreach (CinemaViewModel cinemamodel in Model.UserandMovieViewModel.cinema) {
Html.RenderPartial("MovieEntryEditor", cinemamodel);
}
}
else
{
#{ Html.RenderPartial("MovieEntryEditor", new CinemaViewModel()) };
}
</ul>
<a id="addAnother" href="#">Add another</a>
I am using C# in ASP MVC3. I have two tables from SQL Server.Table names are SMS_User and SMS_Division in SQL Server 2008. When i create a new user, I want to show division id from sms_division table.
SMS_User contains UserName, DivisionID, EmailAddress
SMS_Division contains DivisionID, DivisionName.
Controller Code :
UserController : Controller
{
private NetPerfMonEntities2 db = new NetPerfMonEntities2();
IEnumerableZamZam= db.SMS_Division.Select(c => new SelectListItem { Value = c.divisionid.ToString(), Text = c.divisionid.ToString() } );
}
When I create a new user in User Create() VIEW I want to show a DivisonName as a dropdown list instead of a text box. How I do that ?
#Html.DropDownListFor(model => model.divisionid, (IEnumerable<SelectListItem>) ViewData["Divisions"], "<--Select a divison-->")
#Html.ValidationMessageFor(model => model.divisionid)
I have this error message :
CS0103: The name 'sms_amountlimit2' does not exist in the current context
I'll be assuming a few missing part of your question in my answer, and give you a generic pattern to have a working dropdown list in ASP.NET MVC 3 :
Let's start with the models :
UserModel would be the class representing the data extracted from sms_user
public class UserModel
{
public string Username { get; set; }
public string EmailAddress { get; set; }
public int DivisionId { get; set; }
}
DivisionModel would be the class representing the data extracted from sms_division
public class DivisionModel
{
public int DivisionId { get; set; }
public string DivisionName { get; set; }
}
By Extracted, I mean anything that can transform the data in your Database in instanciated classes. That can be an ORM (EntityFramework or others), or SQL Queries, etc...
Next, is the viewmodel, because it wouldn't make sense to plug an IEnumerable of divisions in UserModel, and I personally don't really like using ViewData when I can avoid it :
public class UserViewModel
{
public UserModel User { get; set; }
public IEnumerable<DivisionModel> Divisions {get; set;}
}
Next, the controller :
public class UserController : Controller
{
public ActionResult Create()
{
List<DivisionModel> divisions = new List<DivisionModel>();
divisions.Add(new DivisionModel() { DivisionId = 1, DivisionName = "Division1" });
divisions.Add(new DivisionModel() { DivisionId = 2, DivisionName = "Division2" });
UserModel user = new UserModel() { Username = "testUser", EmailAddress = "testAddress#test.com" };
return View(new UserViewModel() { User = user, Divisions = divisions });
}
}
I just create the Division list and the user, but you would get then from you database by any means you are using.
And finally the View :
#model ViewModels.UserViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
<p>
#Html.DropDownListFor(model => model.User.DivisionId, new SelectList(Model.Divisions, "DivisionId", "DivisionName"), "-- Select Division --")
#Html.ValidationMessageFor(model => model.User.DivisionId)
</p>
Note that the model binded to the view is the ViewModel.
In your model add a collection of the divisions then create the dropdown list like below:
#Html.DropDownListFor(m => m.SelectedDivisionId,
new SelectList(Model.Divisions, "DivisionId", "DivisionName"),
"-- Select Division --")