2009-03-24 17 views
37

estoy escribiendo mi primera aplicación asp.net mvc y tengo una pregunta acerca personalizados ayudantes HTML:personalizados: Crear ayudante para con el "uso" de apoyo comunicado

Para hacer un formulario, puede utilizar:

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

Me gustaría hacer algo similar con un ayudante HTML personalizado. En otras palabras, quiero cambiar:

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

en:

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

Es esto posible?

Respuesta

47

Aquí es una posible implementación reutilizable en 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() 
     ); 
    } 
} 

En este caso, BeginTr y EndTr escribir directamente en la secuencia de respuesta. Si utiliza los métodos de extensión que devuelven una cadena, que tendrá que ellos salida usando:

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

pweh .. y pensé que esto iba a ser fácil .. Gracias por su esfuerzo. –

+0

Fue solo una implementación rápida y sucia. El delegado "begin" se puede llamar directamente en su método de extensión y la clase DisposableHelper es reutilizable para otras extensiones. – ybo

+0

Ok, lo analizaré más adelante. –

18

Si nos fijamos en la fuente para el ASP.NET MVC (disponible en Codeplex), verá la aplicación de la BeginForm llama finalmente hasta el siguiente código:

implementa la clase
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); 
} 

El MvcForm IDisposable, en su método de eliminación es escribe el </formulario > a la respuesta.

Entonces, lo que tendría que hacer es escribir las etiquetas que desea en el método de ayuda y devolver un objeto que implemente IDisposable ... en su método de eliminación cierre la etiqueta.

31

me trataron siguiendo el consejo dado aquí en MVC3, pero se metió en problemas usando:

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

Cuando usé este código, mi ayudante estaba escribiendo en la secuencia de respuesta ANTES de que mi diseño se procesara. Esto no funcionó bien

En lugar de eso utiliza esto:

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

Gracias montones. Me ahorró montones de tiempo. –

+2

Funcionó para mí en MVC 3 usando el código original escribiendo el contenido html helper justo debajo del cuerpo html. Esto lo solucionó. –

Cuestiones relacionadas