Create a new Model or utilize an Entity Framework class in ASP.NET MVC.

asp.net-mvc design-patterns entity-framework model-view-controller

Question

I am developing a ASP.NET MVC 3 application, i am using entity framework code first in order to create the classes of my app, and i also have a repository in order to perform the operations on it, keeping clean the DBContext and the DBEntities definitions.

My doubt is about the render of the views and the way where a edit model is saved.

If I have this entity that represent a user stored in my DB:

//Entity:
public class User 
{
    [Key]
    public int IdUser { get; set; }
    public string UserName { get; set; }   
    public string Password { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
}

And i want to show a View with the FirstName, LastName, Email and NewPassword, ConfirmPasword and CurrentPassword, in order to let the user change his data, typing the CurrentPassword to confirm the changes, so my doubt is, fieds like ConfirmPasword and CurrentPassword aren´t in my entity so i need to create a new model for this View and the copy the information that i want from my new Model to my database entity in order to save it? Like:

public class UpdateUserModel
{

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

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

    [Required]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "Not valid email")]
    public string Email { get; set; }      

    [DataType(DataType.Password)]
    [Display(Name = "New password")]
    public string NewPasword{ get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm the New Pasword")]
    [Compare("NewPasword", ErrorMessage = "Password doesn´t mach.")]
    public string ConfirmPasword{ get; set; }

    [Required(ErrorMessage = "Need to specify the current password to save changes")]
    [DataType(DataType.Password)]
    [Display(Name = "Current Password")]
    public string CurrentPassword { get; set; }
}

and in the controller i made:

public ActionResult UpdateUser(UpdateUserModel model)
{              
    User u = (User)Membership.GetUser();            
    u.FirstName = model.FirstName;
    u.LastName = model.LastName;
    u.Email = model.Email;

    if (!String.IsNullOrEmpty(model.NewPassword))
    {
        u.Password = FormsAuthentication.HashPasswordForStoringInConfigFile(model.NewPassword.Trim(), "md5");
    }

    repository.UpdateUser(u);

    return View();
}

There are any way of doing this having a controller like:

public ActionResult UpdateUser(User u)
{               
    repository.UpdateUser(u);              
    return View();
}

Because if i have that, how i can add the field like, ConfirmPassword or CurrentPassword in order to made the validation for this specific View.

1
7
7/15/2012 3:31:00 AM

Accepted Answer

If I were you, I wouldn't use domain model in my presentation layer. I would create a view model (another class) which will be very similar to my domain model. I would then use auto-mapping tool to map from my domain model to the view model.

This is a very common scenario, so if you Google for "view and domain" models you should find everything you need.

public class User {
        [Key]
        public int IdUser { get; set; }
        public string UserName { get; set; }   
        public string Password { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }

}

public class UpdateUserViewModel {
    // Original fields

    public string Password  { get; set; }

    public string PasswordConfirmation { get; set;
}

You could then configure auto-mapper to remove your boiler plate code:

public ActionResult ShowUser()
{
    var domainModel = new User(); // I'm assuming that properties are set somewhere
    var viewModel = new UserViewModel();  

    Autommaper.Map(domainModel, viewModel);

    return View(viewModel);
}

This is very rough, but hopefully you get an idea.

Update 1: **

As i understood is better to create a new model for each view and then map it into the entity

It's not just better, it provides better separation of concerns, makes your code easily testable. Just by looking at the name of the class, I can see its purpose UpdateUserViewModel, RegisterUserViewModel etc).

Original fields, in this class is supposed to be the Metadata with the validation and that stuff isn't?

By original fields I mean:

public class UserViewModel{
   public string UserName { get; set; }
   public string FirstName { get; set; }

}

These fields are already in your User class, so I saved my time by not typing them in again.

This will be change my model from MVC to MVVM or not beacuse i still have a controller?

I believe what I've suggested is still an MVC pattern, rather than MVVM.

About the Automaper, are you using github.com/AutoMapper/AutoMapper?

Automapper is something that I have used. There are few tools out there and they do pretty much the same thing. Try out few and find one that suits your requirements the most.

Good luck.

6
3/27/2012 12:27:50 PM

Popular Answer

Usually I use areas for different parts of my project, as an aside of where to put this extra code.

Pretty much you are going to add to your model folder a viewmodel.cs class. Inside this class will hold your definitions for how the data will be modelled in the view. These viewmodels will reflect the parts of the entity you wish the user to interact with. The interaction will be done in the controllers via [HttpGet] where you pass in the view model to be interacted with, and [HttpPost] where you send the model back and then map it to an entity.

ViewModels.cs:

public class UserViewModel
{
 public string UserName { get; set; }
}

SomeController:

public ActionResult getView()
{
 var uvm = new UserViewModel();
 return View(uvm);
}

View getView.cshtml:

@model project.namespace.UserViewModel

@using (Html.BeginForm())
{
 @Html.EditorFor(m => m.UserName)
 <input type="submit" value="New User Name" />
}

Back in controller:

[HttpPost]
public ActionResult getView(UserViewModel model)
{
 var entity = new ActualEntity();
 entity.username = model.UserName;
 //more mapping
 //commit changes somewhere
 return RedirectToAction("getView");
}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow