2013-02-11 11 views
5

Ho un ViewModel che contiene i seguenti:Modo appropriato per impostare i valori predefiniti per ViewModel in MVC4?

public class CreateCardViewModel 
    { 
     [HiddenInput(DisplayValue = false)] 
     public int SetId { get; set; } 

     [Required] 
     public IList<Side> Sides { get; set; } 

     [Required] 
     public int Stage { get; set; } 

     [Required] 
     [DataType(DataType.Date)] 
     [HiddenInput(DisplayValue = false)] 
     public DateTime DateCreated { get; set; } 

     [Required] 
     public bool IsReady { get; set; } 

    } 

Il modello è la seguente:

public class Card 
    { 

     public virtual int CardId { get; set; } 

     // belongs to a Set 
     public virtual int SetId { get; set; } 
     public virtual Set Set { get; set; } 

     // has Sides 
     public virtual IList<Side> Sides { get; set; } 

     // is in a certain Stage 
     public virtual int Stage { get; set; } 

     // is ready to study 
     public virtual bool IsReady { get; set; } 

     public virtual DateTime DateCreated { get; set; } 

    } 

Come posso impostare un valore predefinito per DateCreated?

Il metodo cambierebbe se si desidera inserire un lato vuoto nella creazione dei lati sulla tessera?

risposta

8

Si potrebbe impostare i valori predefiniti nel costruttore:

public CreateCardViewModel() 
{ 
    DateCreated = DateTime.Now; 
    Sides = new List<Side> { new Side() }; 
} 

Caveat: C'è un problema con l'utilizzo DateTime.Now da una prospettiva unit testing. Se esegui il test dell'unità durante la creazione di ViewModel e devi essere in grado di verificare che la data di creazione sia impostata su un valore noto, puoi guardare alla creazione di un concetto separato per il tempo, come descritto in Ayende's blog. Fondamentalmente si crea una funzione statica, SystemTime, che è possibile impostare su un valore noto nei test. Se non la imposti, il valore predefinito è DateTime.Now:

public static class SystemTime 
{ 
    public static Func<DateTime> Now =() => DateTime.Now; 
} 

Il vostro codice del costruttore diventa allora:

public CreateCardViewModel() 
{ 
    DateCreated = SystemTime.Now(); 
    Sides = new List<Side> { new Side() }; 
} 

Se è necessario impostare in realtà il tempo per un valore noto, si esegue questa operazione:

SystemTime.Now =() => new DateTime(2013, 2, 11, 17, 41, 12); 
2

Sono d'accordo sull'approccio SystemTime.

Anche se, personalmente, non mi piace impostare il CreatedDate sul costruttore, poiché ci può essere un breve intervallo di tempo dal momento in cui istanziate l'oggetto e quando lo persistete nel database. (E qui mi si parto dal presupposto sicuramente sono)

Si potrebbe fare tutti i vostri oggetti di dominio ereditano da un'interfaccia simile a questo:

public interface ITimeStamped 
{ 
    DateTime DateCreated { get; set; } 
} 

E poi sul metodo Commit int la classe Context avrei fatto qualcosa in questo modo per impostare la data per tutte le entità che implementano l'interfaccia:

foreach (var entry in ChangeTracker.Entries<ITimeStamped>() 
       .Where(entry => entry.State == EntityState.Added)) 
      { 
       entry.Entity.DateCreated = SystemTime.Now(); 
      } 

in questo modo si è del tutto certo che l'entità è memorizzato con il DateTime corretto quando si è persistito nel database.

Problemi correlati