2013-07-25 14 views
6

Ho una classe modello base, NotificationBase e due modelli derivati, GeneralNotification e ReleaseNotification.Utilizzo di una vista singola per i modelli mvc derivati ​​

public class NotificationBase 
{ 
     public int Id { get; set; } 

     [Required] 
    [StringLength(50, ErrorMessage="Title must not exceed 50 characters.")] 
    public string Title { get; set; } 

    [Required(ErrorMessage="Type is required.")] 
    public int TypeId { get; set; } 

    [Required(ErrorMessage="Importance is required.")] 
    public int ImportanceId { get; set; } 

    public DateTime Created {get; set; } 

    [Required(ErrorMessage="Start date is required.")]   
    public DateTime StartDate { get; set; } 

    [Required(ErrorMessage="End date is required")] 
    public DateTime EndDate { get; set; } 

    [AllowHtml] 
    [Required(ErrorMessage="Details are required")] 
    public string Details { get; set; }     

} 

public class GeneralNotification : NotificationBase 
{ 
    [Required(ErrorMessage="Message is required.")] 
    [StringLength(50, ErrorMessage = "Message must be maximum 50 chararacters long.")] 
    public string Message { get; set; } 
} 

    public class ReleaseNotification : NotificationBase 
{ 
    [Required(ErrorMessage="Version is required.")] 
    public string Version { get; set; } 
} 

Sto tentando di utilizzare una singola vista di modifica per modificare entrambi i tipi di notifica derivati.

Questa vista ha un modello di tipo NotificationBase.

Il problema è che non riesco a ottenere le proprietà aggiunte dei tipi derivati ​​da visualizzare nella vista di modifica. L'invio di un modello del tipo base significa che perdo lungo il percorso le proprietà extra dei tipi derivati.

C'è una soluzione alternativa, oppure devo solo creare viste separate per ogni modello derivato?

risposta

4

È possibile aggiungere un paio di condizioni alla vista. Supponiamo che il vostro punto di vista è fortemente tipizzato con classe di base:

@model NotificationBase 

È possibile controllare per ogni sottoclasse e aggiungere campi corrispondenti (codice non testato qui sotto!):

@if (Model is GeneralNotification) 
{ 
    Html.TextBoxFor(m => ((GeneralNotification) m).Message); 
} 

Lo stesso vale per il secondo sottotipo di corso:

@if (Model is ReleaseNotification) 
{ 
    Html.TextBoxFor(m => ((ReleaseNotification) m).Version); 
} 
+0

Grazie per la rapida risposta, Andrei. Questo è esattamente quello che sto facendo, problema è che questa è una vista di modifica e ho bisogno di visualizzare le proprietà delle entità selezionate. Per un modello GeneralNotification, ho bisogno di visualizzare il valore della proprietà Message. È questo il valore che non posso passare alla mia vista. –

+0

@OctavianEpure, come stai passando il modello alla vista? Puoi condividere un esempio di codice di questo? In teoria, l'esecuzione di 'return View (generalNotificationInstance)' insieme ai frammenti nella risposta sopra dovrebbe darti un risultato atteso. – Andrei

+0

questo è il modello che passo alla vista @model NotificationBase, e nel controller faccio questo NotificationBase model = null; switch (typeId) { case (int) NotificationType.General: model = Servizio.GetGeneralNotification (id); interruzione; case (int) NotificationType.Release: model = Service.GetReleaseNotification (id); interruzione; } vista di ritorno (modello); –

0

Questo può anche essere risolto utilizzando un'interfaccia. Ad esempio se vuoi evitare condizioni nelle tue visualizzazioni. Le visualizzazioni del rasoio possono anche essere fortemente digitate con un'interfaccia.

È possibile utilizzare un'interfaccia completa implementata da NotificationBase con sostituzioni nelle classi derivate. (notare che NotificationBase dovrebbe essere astratto per questo) O implementare interfacce parziali.

Kr

0

Impostare il tipo di modello per il tipo base:

@model NotificationBase 

Poi:

@Html.EditorForModel() 

EditorForModel è abbastanza intelligente per rendere il modulo in base al tipo di cemento trasmesso runtime .

+0

Non riesco a utilizzare EditorForModel, poiché ho bisogno di visualizzare un editor data/ora speciale JAvaScript in vista per i campi StarDate ed EndDate –

+1

Questo è esattamente ciò che sono per "EditorTemplates". o aggiungi un generico modello di editor 'DateTime' ('~/Views/Shared/EditorTemplates/DateTime.cshtml') o decora le proprietà' StartDate' e 'EndDate' con' [UIHint ("JsDateTime")] 'poi' ~/vista/comune/EditorTemplates/JsDateTime.cshtml'. – haim770

0

Problema risolto: ho passato alla vista uno specifico modello di tipo derivato (GeneralNotification/ReleaseNotification) invece di passare un modello di tipo base. La vista è rimasta la stessa e ora funziona.

+0

Ma come si modificano le proprietà extra nella pagina del rasoio, si usa solo la sintassi del rasoio di base come @ Htlm.Textbox ("propName", propValue) – TypingPanda

+0

Penso di aver ricevuto la risposta da @Andrei di seguito. Grazie – TypingPanda

Problemi correlati