Recently I'm confused by "models". Let's say we have a table "Users" in the database including 4 columns, and in the data layer I have a corresponding "User" model.
namespace MyProject.Data
{
public class User
{
public int Id { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public int UserType { get; set; }
}
}
While in the user registration page, usually I have a view model named "User"(or you can name it UserRegistration)
namespace MyProject.Web
{
public class User
{
public string UserName { get; set; }
public string PlainTextPassword { get; set; }
}
}
Also we probably have a user profile page, which has a corresponding view model named "User" or "UserProfile" that has very similar properties(but not 100% same).
First question the above user models are similar, what's the correct way to design?
separate them in different independent classes
this is what I'm currently doing, but some properties are common, I need to set values manually(or using something like AutoMapper)
sharing/inheritance between them
it seems that the "common properties" get shared, we have no "UserName" property in different "User" models. However, the view model in the registration page is very strange because it has properties named "Password" and "PlainTextPassword", and even "UserType", but actually only UserName and PlainTextPassword are set.
-
[HttpPost]
public ActionResult Register(User user)
{
//only user.UserName and user.PlainTextPassword are useful
//however you will have user.Password, user.UserType with default values
//it even breaks the validation if you use ModelState.IsValid
}
It seems option 1 is better? Correct me if I'm wrong or you have another idea. Then here comes another question based on option 1.
Second question We have MyProject.Web.User as the view model and MyProject.Data.User as the data model. The registration page posts a MyProject.Web.User instance to my controller, finally I need to save it to database via MyProject.Data.User. Should it looks like this:
//the controller in the web project
[HttpPost]
public ActionResult Register(User user)
{
UserManager.Register(user.UserName, user.PlainTextPassword);
//blabla
}
//UserManager in the business layer
public void Register(string userName, string plainTextPassword)
{
//validation
//set properties to MyProject.Data.User
//save the changes to db (probably via EF)
}
you can see the signature of UserManager.Register grows if more properties added, e.g. string address, string mobile
. I think a "user" model is necessary here. MyProject.Web.User is located in the web so it can't be used in UserManager
. While MyProject.Data.User is located in the data layer, if we use MyProject.Data.User here, then MyProject.Web project needs to add a reference MyProject.Data, but currently the reference relationship is UI->Core(the business)->Data. What's the correct design?
This is what worked for me in the past.
In your scenario, I'd create a User
entity (in another project - probably called Entities or Models). Then in my UI layer I'd create bunch of view specific ViewModels (you can of course have a base ViewModel shared between some of the views), for example something like:
// This goes in MyProject.Web/ViewModels ...
public abstract class UserSecurityViewModel {
// stuff that is shared between the other ViewModels
public string Username { get; set; }
public string Password { get; set; }
// you get the idea ...
}
public class RegistrationViewModel : UserSecurityViewModel {
// Registration specific properties
public string Email { get; set; }
// more ...
}
public class LoginViewModel : UserSecurityViewModel {
// you don't need the email here ...
public bool RememberMe { get; set; }
}
Then of course I'd use something like AutoMapper
to map between the ViewModels and the Models (in your case User
).
For example:
[HttpPost]
public ActionResult Register(RegistrationViewModel viewModel) {
User user = viewModel.ToUser(); // <-- this is an AutoMapper helper
// now pass that to your business logic layer and do magic
_userManager.Register(user);
}
I hope I'm making sense (and that I didn't misunderstand you).
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments