39 votes

Aides HTML personnalisées: Créer une aide avec "using" statement support

J'écris ma première application asp.net mvc et j'ai une question à propos des helpers HTML personnalisés:

Pour créer un formulaire, vous pouvez utiliser:

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

J'aimerais faire quelque chose de similaire avec un assistant HTML personnalisé. En d'autres termes, je veux changer:

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

dans:

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

Est-ce possible?

49voto

ybo Points 8870

Voici une implémentation réutilisable possible 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()
        );
    }
}
 

Dans ce cas, BeginTr et EndTr écrivent directement dans le flux de réponses. Si vous utilisez des méthodes d'extension qui renvoient une chaîne, vous devrez les générer en utilisant:

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

33voto

Doug Clutter Points 1332

J'ai essayé de suivre les conseils donnés ici dans MVC3, mais j'ai eu du mal à utiliser:

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

Lorsque j'ai utilisé ce code, mon assistant écrivait dans le flux de réponses AVANT le rendu de ma mise en page. Cela n'a pas bien fonctionné.

Au lieu de cela, j'ai utilisé ceci:

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

19voto

Kieron Points 10261

Si vous regardez la source de la ASP.NET MVC (disponible sur Codeplex), vous verrez la mise en œuvre de la BeginForm finalement appels vers le bas pour le code suivant:

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);
}

Le MvcForm classe implémente IDisposable, dans sa méthode dispose est écrit le </forme> pour la réponse.

Donc, ce que vous devez faire est d'écrire les balises que vous souhaitez à l'aide de la méthode retourne un objet qui implémente IDisposable...dans la méthode dispose de fermer la balise off.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X