Reputation: 311
I have developed ASP.Net applications over the years using Webforms and I have done a few MVC applications but never actually use the framework in full, this is due to the time constraint of most of the projects. Although, I'm using the MVC structure I'm still using the old ways i.e. not using @Html.BeginForm etc. instead I user the tag etc.
I've just recently started another project, but this time I want to use the correct MVC features.
I have been reading about Best Practices in Design Patterns. In my Solution, I have Projects for the MVC application, Testing, and for Data (which is a class library that connects to the database). I'm not using Entity Framework but I'm still wondering about the proper way of creating classes for View Models.
On my Data library class I have a class call Users
public class User
{
public long Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Email { get; set; }
[Required]
public long RoleId { get; set; }
}
The fields I want to render on the View are Name, Email, and a dropdownlist for the RoleId. So for a Model on the View, is it correct that it doesn't have to be the same as my Data Class? Is below a correct Model View Class?
public class UserModel
{
public Data.User User { get; set; }
public IEnumerable<KeyValuePair<long,string>> RoleList { get; set; }
}
The reason for asking is that, initially, I always assume that Model classes should be the same as your Data classes which I have read in Google that in most cases it's not. Is this correct?
Is this the correct implementation of the view?
@using (Html.BeginForm())
{
@Html.LabelFor(m=>m.User.Name)
@Html.TextAreaFor(m=>m.User.Name)
<br/>
@Html.LabelFor(m => m.User.Email)
@Html.TextAreaFor(m => m.User.Email)
<br />
@Html.LabelFor(m => m.User.RoleId)
@Html.DropDownListFor(m => m.User.RoleId, new SelectList(Model.RoleList,
"Value", "Key"),"--Please Select--")
}
Upvotes: 3
Views: 7460
Reputation: 507
the best approach you can take is to create a model ( new class ) for each view that you want to expose data / capture data on. This is argueably more work, but it really has some massive advantages. First and foremost, you don't end up tightly coupling your view to your domain, ie you Users table could have 20 columns but you just want to expose 2 to the login page ( username/password ). Secondly, through the MVC framework and razor in particular, you get some great help with regards to things like validation ( both server side and client side ) as well as things such as display name etc. Also, with regards to managing your dependency hierarchy, you wouldn't want to litter all of your domain models with references to System.Web.MVC aarrrgh!!
The "more work" part comes in in the controller where you will need to validate your view model and then translate your model objects to domain objects so that your business classes all work with a consistent domain model from then on.
Just with regards to your model class proposal, I would do it more like this
public class UserModel
{
[Required]
[Display(Name = "Name")]
public string Name { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email Address")]
public string EmailAddress { get; set; }
[Required]
[Display(Name = "Roles")]
public IEnumerable<KeyValuePair<long, string>> RoleList { get; set; }
}
As you can see above, because I have a granular model that can back the view completely ( as opposed to having a reference to the User object ) I can now add specific validation to each field as required
I'm sure there are tons of even better reasons to go this route that i can't think of right now, but I think this will get you thinking along the right lines. happy coding.
Upvotes: 3
Reputation: 62498
Model class represents the business side of the application, as In your case you have a UserModel class which is having information of user and the collection with roles of it, which the Data Model is specific to repository i.e. database table in your case, so Data Model normally represents the table of the database that we have. Hope it makes sense.
You can also refer to to the following post which asks similar thing i think:
https://stackoverflow.com/a/2446051/1875256
Upvotes: 2