7

Sto sviluppando un'applicazione ASP.NET MVC 3, sto utilizzando il codice del framework di entità prima per creare le classi della mia app e ho anche un repository per eseguire le operazioni su di esso, mantenendo pulite le definizioni di DBContext e DBEntities.ASP.NET MVC: crea un nuovo modello o utilizza una classe Entity

Il mio dubbio riguarda il rendering delle viste e il modo in cui viene salvato un modello di modifica.

Se ho questa entità che rappresentano un utente memorizzate nel mio 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; } 
} 

e voglio mostrare una vista con il Nome, Cognome, Email e NuovaPassword, ConfirmPasword e CurrentPassword, in modo da permettere l'utente cambia i suoi dati, digitando CurrentPassword per confermare le modifiche, quindi il mio dubbio è che arci come ConfirmPasword e CurrentPassword non sono nella mia entità quindi ho bisogno di creare un nuovo modello per questa vista e copiare le informazioni che voglio da il mio nuovo modello alla mia entità di database per salvarlo? Come:

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

e nel controller ho fatto:

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

Non ci sono alcun modo di fare questo con un controller simile:

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

Perché se ho che, come ho puoi aggiungere il campo come, ConfirmPassword o CurrentPassword per fare la convalida per questa specifica vista.

risposta

6

Se fossi in te, non utilizzerei il modello di dominio nel mio livello di presentazione. Creerei un modello di visualizzazione (un'altra classe) che sarà molto simile al mio modello di dominio. Vorrei quindi utilizzare lo strumento di mappatura automatica per mappare dal modello di dominio al modello di visualizzazione.

Questo è uno scenario molto comune, quindi se utilizzi Google per i modelli "view e domain" dovresti trovare tutto ciò di cui hai bisogno.

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

È quindi possibile configurare Auto-mapper per rimuovere il codice piastra della caldaia:

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

Questo è molto ruvida, ma si spera si ottiene un idea.

Update 1: **

Per quanto ho capito è meglio creare un nuovo modello per ogni vista e quindi mappare in dell'entità

Non è solo meglio, fornisce una migliore separazione delle preoccupazioni, rende il tuo codice facilmente verificabile. Solo guardando il nome della classe, posso vedere il suo scopo UpdateUserViewModel, RegisterUserViewModel ecc.).

I campi originali, in questa classe dovrebbero essere i metadati con la convalida e che roba non è?

da campi originali intendo:

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

} 

Questi campi sono già nella tua classe User, quindi ho salvato il mio tempo non li digitando di nuovo.

Questo cambierà il mio modello da MVC a MVVM o meno perché ho ancora un controller?

Credo che quello che ho suggerito sia ancora un pattern MVC, piuttosto che MVVM.

Informazioni su Automaper, stai utilizzando github.com/AutoMapper/AutoMapper?

L'automapper è qualcosa che ho usato. Ci sono pochi strumenti là fuori e fanno praticamente la stessa cosa. Prova alcuni e trova quello più adatto alle tue esigenze.

Buona fortuna.

+1

Ok, ho capito. Come ho capito è meglio creare un nuovo modello per ogni vista e quindi mapparlo nell'entità. Cosa significa // I campi originali, in questa classe si suppone che siano i metadati con la convalida e che roba non lo è? Questo cambierà il mio modello da MVC a MVVM o meno perché ho ancora un controller? Informazioni su Automaper, stai utilizzando https://github.com/AutoMapper/AutoMapper? – juan25d

+0

Vedere l'aggiornamento 1 –

+0

Quindi dove dovrei scrivere la convalida e i metadati? nella classe UserViewModel isnt't? – juan25d

1

Di solito utilizzo le aree per le diverse parti del mio progetto, oltre a dove mettere questo codice extra.

Praticamente aggiungere alla cartella del modello una classe viewmodel.cs. All'interno di questa classe verranno mantenute le tue definizioni per il modo in cui i dati verranno modellati nella vista. Questi viewmodels rifletteranno le parti dell'entità con cui desideri interagire l'utente. L'interazione verrà effettuata nei controller tramite [HttpGet] in cui si passa il modello di visualizzazione con cui interagire e [HttpPost] in cui si invia il modello indietro e quindi si esegue il mapping su un'entità.

ViewModels.cs:

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

SomeController:

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

Vista getView.cshtml:

@model project.namespace.UserViewModel 

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

Già nel controllore:

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

Questo è più o meno quello che ho ora, il problema è che voglio saltare il problema di mappare tutte le volte la mia entità nel modelview e viceversa, ma con la tua risposta penso che sia l'unico modo per avere una diversa convalida/proprietà da un'entità a una vista. Grazie! – juan25d

Problemi correlati