7

Estoy desarrollando una aplicación ASP.NET MVC 3, estoy usando el código entidad marco primero para crear las clases de mi aplicación, y también tengo un repositorio para realizar las operaciones en él, manteniendo limpias las definiciones DBContext y DBEntities.ASP.NET MVC - crear un nuevo modelo o utilizar una clase de estructura Entity

Mi duda es sobre el procesamiento de las vistas y la forma en que se guarda un modelo de edición.

Si tengo esta entidad que representa a un usuario almacenado en mi 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; } 
} 

Y quiero mostrar una vista con el Nombre, Apellidos, Correo electrónico y contraseñaNueva, ConfirmPasword y CurrentPassword, a fin de permitir el usuario cambia sus datos, escribiendo CurrentPassword para confirmar los cambios, entonces mi duda es que fieds como ConfirmPasword y CurrentPassword no están en mi entidad, así que necesito crear un nuevo modelo para esta vista y copiar la información que quiero de mi nuevo modelo a mi entidad de base de datos para guardarlo? Al igual que:

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; } 
} 

y en el controlador que hice:

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(); 
} 

Hay alguna manera de hacer esto que tiene un controlador como:

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

Porque si tengo que, como me puede agregar el campo como, ConfirmPassword o CurrentPassword para realizar la validación de esta Vista específica.

Respuesta

6

Si yo fuera usted, no usaría el modelo de dominio en mi capa de presentación. Crearía un modelo de vista (otra clase) que será muy similar a mi modelo de dominio. Luego utilizaría la herramienta de asignación automática para mapear desde mi modelo de dominio al modelo de vista.

Este es un escenario muy común, por lo que si busca modelos de "vista y dominio" en Google, debería encontrar todo lo que necesita.

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; 
} 

A continuación, puede configurar automáticamente mapeador para eliminar el código de placa de la caldera:

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); 
} 

Esto es muy duro, pero espero que se obtiene una idea.

Actualización 1: **

que he entendido es mejor crear un nuevo modelo para cada vista y asigne en la entidad

No es sólo mejor, proporciona una mejor separación de las preocupaciones, hace que su código sea fácilmente comprobable. Con solo mirar el nombre de la clase, puedo ver su propósito UpdateUserViewModel, RegisterUserViewModel, etc.

Los campos originales, en esta clase se supone que son los metadatos con la validación y esas cosas no?

Por campos originales que quiero decir:

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

} 

Estos campos ya están en su clase de usuario, por lo que salvó mi tiempo al no escribir en ellos de nuevo.

Esto cambiará mi modelo de MVC a MVVM o no porque todavía tengo un controlador?

Creo que lo que he sugerido sigue siendo un patrón MVC, en lugar de MVVM.

Acerca de la Automaper, ¿está utilizando github.com/AutoMapper/AutoMapper?

Automapper es algo que he usado. Hay pocas herramientas y hacen más o menos lo mismo. Pruebe algunos y encuentre uno que se adapte mejor a sus requisitos.

Buena suerte.

+1

Ok, lo entiendo. Como he entendido, es mejor crear un nuevo modelo para cada vista y luego asignarlo a la entidad. ¿Qué significa // Campos originales, en esta clase se supone que son los metadatos con la validación y esas cosas no? ¿Esto cambiará mi modelo de MVC a MVVM o no porque todavía tengo un controlador? Acerca de la Automaper, ¿está utilizando https://github.com/AutoMapper/AutoMapper? – juan25d

+0

Consulte la actualización 1 –

+0

Entonces, ¿dónde debería escribir la validación y los metadatos? en la clase UserViewModel isnt't? – juan25d

1

Normalmente utilizo áreas para diferentes partes de mi proyecto, aparte de dónde colocar este código adicional.

Bastante vas a agregar a la carpeta de tu modelo una clase viewmodel.cs. Dentro de esta clase se incluirán sus definiciones sobre cómo se modelarán los datos en la vista. Estos modelos de vista reflejarán las partes de la entidad con las que desea que el usuario interactúe. La interacción se realizará en los controladores a través del [HttpGet] donde pasa el modelo de vista para interactuar con, y [HttpPost] donde envía el modelo de regreso y luego lo mapea a una entidad.

ViewModels.cs:

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

SomeController:

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

Ver getView.cshtml:

@model project.namespace.UserViewModel 

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

De vuelta en el controlador:

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

Esto es más o menos lo que tengo ahora, el problema es que quiero omitir el problema de mapear todas las veces mi entidad en la vista de modelo y viceversa, pero con su respuesta creo que es la única forma de tener una validación/propiedades diferentes de una entidad a una vista. ¡Gracias! – juan25d

Cuestiones relacionadas