10

Se si legge this article on Validation with the Data Annotation Validators, viene mostrato che è possibile utilizzare l'attributo MetadataType per aggiungere attributi di convalida alle proprietà su classi parziali. Si utilizza questo quando si lavora con ORM come LINQ a SQL, Entity Framework o Subsonic. Quindi è possibile utilizzare la convalida lato client e lato server "automagic". Gioca molto bene con MVC.Quando si utilizzano le annotazioni di dati con MVC, Pro e Contro di utilizzare un'interfaccia rispetto a MetadataType

Tuttavia, un mio collega ha utilizzato un'interfaccia per ottenere esattamente lo stesso risultato. sembra quasi esattamente la stessa cosa e realizza funzionalmente la stessa cosa. Così, invece di fare questo:

[MetadataType(typeof(MovieMetaData))] 
public partial class Movie 
{ 
} 

public class MovieMetaData 
{ 
    [Required] 
    public object Title { get; set; } 

    [Required] 
    [StringLength(5)] 
    public object Director { get; set; } 


    [DisplayName("Date Released")] 
    [Required] 
    public object DateReleased { get; set; } 
} 

Lo ha fatto:

public partial class Movie :IMovie 
{ 
} 

public interface IMovie 
{ 
    [Required] 
    object Title { get; set; } 

    [Required] 
    [StringLength(5)] 
    object Director { get; set; } 


    [DisplayName("Date Released")] 
    [Required] 
    object DateReleased { get; set; } 
} 

Quindi la mia domanda è, quando si fa la differenza in realtà importa?

I miei pensieri sono che le interfacce tendono ad essere più "riutilizzabili" e che la creazione di una sola classe non ha molto senso. Potresti anche argomentare che potresti progettare le tue classi e le tue interfacce in un modo che ti permetta di usare interfacce su più oggetti, ma mi sembra che stia cercando di adattare i tuoi modelli a qualcos'altro, quando dovrebbero davvero stare da soli. Cosa ne pensi?

+0

Ho fatto esattamente questo e non ha funzionato ...: -S – Alxandr

risposta

3

Mi piace l'approccio dell'interfaccia in quanto consente di definire un contratto per il modello che è possibile utilizzare per adattare le classi generate ORM a. Ciò consentirebbe di disaccoppiare l'app dal framework ORM e ottenere un maggiore utilizzo dell'interfaccia MetadataType in quanto serve come metadati di convalida dei dati e un contratto per il modello. È inoltre possibile decorare la tua interfaccia con gli attributi di serializzazione per l'utilizzo in WCF che ottengono maggiore utilizzo dall'interfaccia. Ho seguito alcuni dei primi blog che raccomandavano la creazione di una classe di metadati, ma ancora una volta penso che la soluzione dell'interfaccia sia una buona idea.

+0

Sono d'accordo. In realtà le annotazioni sui dati mi hanno sempre fatto sentire a disagio perché ho sentito che mentre l'interfaccia utente che li metteva sul modello violava la separazione delle preoccupazioni. L'uso di interfacce annotate è una lunga strada per affrontare queste preoccupazioni. –

1

Non vedo alcuna differenza funzionale tra i due approcci. Non sono sicuro che la riusabilità sia davvero importante qui, dato che la validazione sarà più spesso su ViewModels "one-off" che probabilmente non otterranno molto, se non nessuno, riutilizzo.

2

Se queste due opzioni sono le due con cui sono presentato, personalmente sceglierei personalmente l'interfaccia, semplicemente perché penso che sia più pulito. Ma questo è interamente basato sul gusto personale - non ne so abbastanza del funzionamento interno di .NET per dirlo con certezza, ma non conosco alcun caso in cui la funzionalità effettiva dei due approcci sarebbe diversa.

D'altra parte, un approccio molto migliore sarebbe quella di utilizzare oggetti di trasferimento dati (DTO) per l'invio di dati avanti e indietro, e hanno i requisiti di validazione su di loro. Cioè, invece di richiedere che l'oggetto Movie soddisfi tutti i requisiti di convalida, è necessario che un oggetto MovieInput soddisfi tutti questi requisiti e quindi creare il codice per mappare uno corretto in un Movie. (Se non vuoi farlo manualmente, puoi usare AutoMapper o qualche altra utility).

Il concetto è sostanzialmente quella di avere qualcosa come un oggetto View Modello sulla strada in altrettanto bene come sulla strada fuori - Potrei anche avere cerchiamo MovieInput essere chiamati MovieViewModel e usarlo per il trasferimento di dati sia dentro che fuori dal server.

+0

Quindi, se si dispone di una facciata tra l'interfaccia utente e il livello di "persistenza", e si limitano a visualizzare questi DTO alle viste, dove si inserisce e si integra la convalida più complessa (regole aziendali)? Implementare 'IValidateableObject' nei DTO? Ciò sembra sbagliato ... perché tutto sommato, vogliamo legare tutto all'interfaccia utente utilizzando i punti di integrazione forniti da MVC (e dataannotations e ivalidateableobject potrebbero essere utilizzati anche all'esterno di MVC). – kamranicus

+0

@subkamran: vedo due possibili scenari qui. 1) Hai bisogno esattamente dello stesso input indipendentemente dall'interfaccia utente. In questo caso, il livello dell'interfaccia utente dovrebbe essere necessario per creare un'istanza di un DTO comune, in cui è possibile applicare le regole di convalida e il DTO può essere utilizzato indipendentemente dal livello dell'interfaccia utente. 2) L'input sarà diverso in diversi livelli dell'interfaccia utente per produrre lo stesso tipo di oggetto nel livello aziendale. In questo caso, sono necessari DTO specifici dell'interfaccia utente, ma le regole di convalida possono ancora essere applicate al DTO. Poiché i requisiti di input sono diversi, anche le regole di convalida sono valide. Quindi puoi sempre convalidare i tuoi DTO. –

+0

Capisco la tua logica e ha senso, ma non perderò, per esempio, tutta l'integrazione Javascript? Perché il più delle volte, le mie opinioni trattano un sottoinsieme delle proprietà dell'oggetto (un DTO) ma anche con proprietà non correlate solo per la vista (ad esempio un dizionario di ricerca per gli elenchi selezionati). Quindi non posso davvero accettare quelli come input dal mio servizio perché hanno proprietà inutili di cui non mi importa. Forse, potrei ereditare da questi DTO e creare ViewModels al di fuori di essi per il consumo della vista MVC. Questo crea solo più oggetti galleggianti, ma forse va bene? – kamranicus

Problemi correlati