2009-03-24 13 views
37

sto scrivendo la mia prima applicazione mvc asp.net e ho una domanda circa aiutanti HTML personalizzato:personalizzati aiutanti HTML: Crea helper con "usando" il supporto dichiarazione

Per fare un modulo, è possibile utilizzare:

<% using (Html.BeginForm()) {%> 
    *stuff here* 
<% } %> 

Mi piacerebbe fare qualcosa di simile con un helper HTML personalizzato. In altre parole, voglio cambiare:

Html.BeginTr(); 
Html.Td(day.Description); 
Html.EndTr(); 

in:

using Html.BeginTr(){ 
    Html.Td(day.Description); 
} 

è possibile?

risposta

47

Ecco una possibile implementazione riutilizzabile in C#:

class DisposableHelper : IDisposable 
{ 
    private Action end; 

    // When the object is created, write "begin" function 
    public DisposableHelper(Action begin, Action end) 
    { 
     this.end = end; 
     begin(); 
    } 

    // When the object is disposed (end of using block), write "end" function 
    public void Dispose() 
    { 
     end(); 
    } 
} 

public static class DisposableExtensions 
{ 
    public static IDisposable DisposableTr(this HtmlHelper htmlHelper) 
    { 
     return new DisposableHelper(
      () => htmlHelper.BeginTr(), 
      () => htmlHelper.EndTr() 
     ); 
    } 
} 

In questo caso, BeginTr e EndTr scrivere direttamente nel flusso di risposta. Se si utilizzano metodi di estensione che restituiscono una stringa, dovrete uscita utilizzando:

htmlHelper.ViewContext.HttpContext.Response.Write(s) 
+0

pweh .. e ho pensato che questo sarebbe stato facile .. Grazie per il vostro sforzo. –

+0

Era solo un'implementazione rapida e sporca. Il delegato "inizio" può essere chiamato direttamente nel tuo metodo di estensione e la classe DisposableHelper è riutilizzabile per altre estensioni – ybo

+0

Ok grazie, guarderò meglio in seguito. –

18

Se si guarda alla sorgente per l'ASP.NET MVC (disponibile su Codeplex), vedrete l'attuazione del BeginForm chiama infine verso il seguente codice:

static MvcForm FormHelper(this HtmlHelper htmlHelper, string formAction, FormMethod method, IDictionary<string, object> htmlAttributes) 
{ 
    TagBuilder builder = new TagBuilder("form"); 
    builder.MergeAttributes<string, object>(htmlAttributes); 
    builder.MergeAttribute("action", formAction); 
    builder.MergeAttribute("method", HtmlHelper.GetFormMethodString(method), true); 
    htmlHelper.ViewContext.HttpContext.Response.Write(builder.ToString(TagRenderMode.StartTag)); 

    return new MvcForm(htmlHelper.ViewContext.HttpContext.Response); 
} 

Il MvcForm implementa classe IDisposable, nel suo metodo di dispose scrive </form > nella risposta.

Quindi, quello che dovresti fare è scrivere i tag che vuoi nel metodo helper e restituire un oggetto che implementa IDisposable ... nel suo metodo di smaltimento chiude il tag.

31

ho provato seguendo il consiglio dato qui in MVC3, ma mi sono imbattuto in problemi con l'uso:

htmlHelper.ViewContext.HttpContext.Response.Write(...); 

Quando ho usato questo codice, il mio helper stava scrivendo nello stream di risposta PRIMA che il mio layout fosse reso. Questo non ha funzionato bene.

Invece ho usato questo:

htmlHelper.ViewContext.Writer.Write(...); 
+2

Grazie mille. Mi ha salvato un sacco di tempo. –

+2

Ha funzionato per me in MVC 3 utilizzando il codice originale è stato scritto il contenuto helper html proprio sotto il corpo html. Questo l'ha risolto. –

Problemi correlati