Ayudantes HTML personalizados:Crear ayuda con soporte para declaraciones de "uso"
-
21-08-2019 - |
Pregunta
Estoy escribiendo mi primera aplicación asp.net mvc y tengo una pregunta sobre los asistentes HTML personalizados:
Para crear un formulario, puedes utilizar:
<% using (Html.BeginForm()) {%>
*stuff here*
<% } %>
Me gustaría hacer algo similar con un asistente HTML personalizado.En otras palabras, quiero cambiar:
Html.BeginTr();
Html.Td(day.Description);
Html.EndTr();
en:
using Html.BeginTr(){
Html.Td(day.Description);
}
es posible?
Solución
Aquí hay 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
escriba directamente en el flujo de respuesta.Si usa métodos de extensión que devuelven una cadena, deberá generarlos usando:
htmlHelper.ViewContext.HttpContext.Response.Write(s)
Otros consejos
He intentado siguiendo el consejo dado aquí en MVC3, pero me encontré con problemas para usar:
htmlHelper.ViewContext.HttpContext.Response.Write(...);
Cuando utilice este código, mi ayudante estaba escribiendo en la corriente de respuesta antes de que mi diseño se hizo. Esto no funcionó bien.
En lugar utilicé esta:
htmlHelper.ViewContext.Writer.Write(...);
Si observa la fuente de ASP.NET MVC (disponible en Códigoplex), verá que la implementación de BeginForm finalmente llama al siguiente código:
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);
}
La clase MvcForm implementa IDisposable, en su método de disposición escribe el </form> en la respuesta.
Entonces, lo que tendría que hacer es escribir las etiquetas que desea en el método auxiliar y devolver un objeto que implemente IDisposable... en su método de eliminación, cierre la etiqueta.