2011-01-27 15 views
18

Su Web Forms abbiamo UserControls. Questi controlli hanno un code-behind e possono essere utilizzati in diversi progetti/soluzioni che non dipendono da altre cose.UserControl equivalente in MVC3?

Voglio creare un controllo che esegue il rendering di alcuni controlli e avrebbe alcuni collegamenti che "attivano un evento". Voglio che non vengano allegati sul mio sito Web, voglio poter utilizzare lo stesso "controllo" su un altro sito web. Qual è l'equivalente in MVC? È possibile compilare una vista con un controller e utilizzare la DLL altrove?

+0

correlati a (ma non a un duplicato di) queste domande: [73902] (http://stackoverflow.com/questions/73902/ asp-net-mvc-components), [810187] (http://stackoverflow.com/questions/810187/is-there-an-equivalent-to-monorail-view-components-for-the-asp-net-mvc -framework) –

risposta

17

L'equivalente funzionale più simile ai controlli utente riutilizzabili in stile WebForms in MVC sono helper HTML. Un helper html è un metodo che restituisce alcuni markup. L'approccio consigliato è quello di implementare loro sotto forma di metodi di estensione off HtmlHelper o qualche altra proprietà di una pagina MVC:

public static IHtmlString MyControl(this HtmlHelper helper, string value) { 
    return new HtmlString("<p>" + value + "</p>"); 
} 

È possibile aggiungere questo metodo per il vostro progetto MVC direttamente o è possibile aggiungerlo a una classe separata biblioteca. L'unica cosa che la libreria di classi deve fare riferimento è System.Web.Mvc.dll per il riferimento HtmlHelper (potrebbe anche essere necessario System.Web.dll se si utilizzano più tipi).

Di solito li chiamate dalla visualizzazione in questo modo (questo esempio utilizza la sintassi Razor che c'è di nuovo in MVC 3)

@Html.MyControl("my value") 

Mentre aiutanti superficialmente html emettono markup proprio come controlli utente, ci sono differenze significative. Il più importante è che le viste MVC non hanno il concetto del ciclo di vita della pagina WebForms. Ciò significa che a differenza dei controlli utente, gli helper html vengono visualizzati in un unico passaggio. Non ci sono fasi multiple come Init, Load, Render etc in WebForms in cui è possibile collegare eventi lato server per interagire con altri controlli nella pagina.

A seconda degli specifici tipi di eventi di cui si sta parlando, potrebbero essere necessarie tecniche MVC-centric appropriate per risolvere il proprio compito.Potresti fornire maggiori dettagli su cosa vuoi fare? Gli helper HTML possono essere abbastanza potenti. Ad esempio, i controlli di input MVC incorporati come TextBoxFor possono collegare la convalida lato client ecc.

+0

Potrebbe anche usare una normale "vista", renderla come "parziale" e usare un ViewModel come "codice dietro"? Dal momento che un UserControl è un ASCX, per come lo vedo io, l'equivalente più vicino è una vista parziale con un ViewModel. –

+1

@rockinthesixstring I partial non si adattano ai requisiti dell'OP che i componenti riutilizzabili potrebbero essere definiti in un assembly separato incluso da alcune diverse applicazioni (almeno non senza la scrittura di motori di visualizzazione personalizzati o provider di percorsi virtuali che caricheranno le viste dagli assiemi ecc.) . – marcind

+0

sì buona chiamata. Anche se penso che UserControl sia il fraseggio sbagliato. Forse "Custom Control" è una misura migliore? –

3

Poiché "eventi" non esistono nello stesso senso in MVC come nei WebForm, soddisfare tutte le vostre esigenze sarà piuttosto complicato.

Per il livello UI dell'equivalente UserControl, è necessario utilizzare PartialView, possibilmente situato nella cartella Views/Shared/Templates in base a se si desidera che sia associato a un determinato tipo di modello o meno.

Per il back-end ("evento"), è probabilmente necessario implementare un controller che è possibile inviare le richieste dai collegamenti e che supporta tutti i comportamenti necessari.

Per utilizzare queste funzioni in vari progetti, è necessario copiare sia il controller che il modello/vista parziale. Certo, potrebbe non essere semplice da riutilizzare come un controllo utente do-it-all da WebForms, ma questa è una limitazione che viene fornita con una netta separazione di preoccupazioni, e ciò sarebbe evidente in un ben progettato, basato su livelli Applicazione WebForms pure.

Aggiorna in risposta ad un commento sul "limitazione" di separazione dei problemi che ho citato:
Il controller può naturalmente essere distribuito in un assembly separato, con il suo montaggio di prova ecc Tuttavia, compreso il controllore assemblaggio (o gruppi) e la vista parziale/modello con il front-end è probabilmente un'altra cosa da fare (ad es. forse non riuscire a fare) che copiare semplicemente un controllo utente con il code-behind (che sono memorizzati accanto a ciascuno altro).

+0

-1: stavo andando a revocare questo fino alla linea "netta separazione delle preoccupazioni". Che cosa si tratta della separazione dei problemi che impedisce a un controller di essere incorporato in un altro assembly e di fare riferimento a molte applicazioni MVC? Le viste sono HTML, più o meno, e dovrebbero essere condivise in quanto tali, ma perché non tutto il codice .NET dovrebbe essere in uno o più assembly separati, testabili? –

+1

Sicuro: il controller può essere definitivamente inserito in un assembly (testabile) separato e condiviso indipendentemente dal resto del progetto. Non dico che non sia fattibile (direi anche che ne vale la pena!), Ma è decisamente più complicato che sollevare un controllo utente e il file code-behind (se ne hai anche uno) da un progetto all'altro, e fa tutta la magia per conto proprio. * Questo * è limitato dalla netta separazione delle preoccupazioni - un costo che sono più che disposto a prendere. –