2012-05-17 5 views
18

Ich suchte, konnte aber keine schnellen Lösungen für eine MVC 3 htmlhelper um eine Wrapper-Methode zu erstellen. Was ich suche ist so etwas wie:MVC 3 htmlhelper Erweiterung Methode, um Inhalt

@html.createLink("caption", "url") 
{ 
    <html> content in tags </html> 
} 

das Ergebnis

<a href="url" title="Caption"> 
    <html> content in tags </html> 
</a> 

Jede Hilfe mit diesem haben sollte.

+0

Fragen Sie, ob es möglich ist, so etwas zu tun: '@ Html.ActionLink (" Hallo World "," MyAction ")'? – CallumVass

+0

Nein, nicht das. Ich weiß, es gibt BeginForm() und EndForm() Art Ansatz, um diese Art von Szenario zu behandeln, aber wenn dies in großem Umfang tun, kann ein Problem verursachen, wenn Sie ein Ende-Tag vergessen. – Sanj

+0

Ich bin mir nicht sicher, ob ich weiß, was du meinst?Sie würden 'BeginForm' in diesem Szenario nicht verwenden? Sie würden 'BeginForm' verwenden, um ein Formular und keinen Ankerlink zu erstellen. – CallumVass

Antwort

42

Die Art und Weise, dass dies mit Begin geschehen ist, ist, dass der Rückgabetyp MvcForm impliments IDisposable so, dass, wenn innerhalb einer using Anweisung verwendet, die Dispose Methode MvcForm schreibt das abschließende </form> Tag aus.

Sie können eine Erweiterungsmethode schreiben, die genau dasselbe tut.

Hier ist eine, die ich gerade schrieb, um zu demonstrieren.

Zunächst einmal, die Erweiterungsmethode:

public static class ExtensionTest 
{ 
    public static MvcAnchor BeginLink(this HtmlHelper htmlHelper) 
    { 
     var tagBuilder = new TagBuilder("a"); 
     htmlHelper.ViewContext.Writer 
         .Write(tagBuilder.ToString(
              TagRenderMode.StartTag)); 
     return new MvcAnchor(htmlHelper.ViewContext); 
    } 
} 

Und hier ist unser neuer Typ, MvcAnchor:

public class MvcAnchor : IDisposable 
{ 
    private readonly TextWriter _writer; 
    public MvcAnchor(ViewContext viewContext) 
    { 
     _writer = viewContext.Writer; 
    } 

    public void Dispose() 
    { 
     this._writer.Write("</a>"); 
    } 
} 

In Ihre Ansichten können Sie jetzt tun:

@{ 
    using (Html.BeginLink()) 
    { 
     @Html.Raw("Hello World") 
    } 
} 

Was das Ergebnis ergibt:

<a>Hello World</a> 

diese leicht Erweiterung mit Ihren genauen Anforderungen zu bewältigen:

public static MvcAnchor BeginLink(this HtmlHelper htmlHelper, 
            string href, 
            string title) 
{ 
    var tagBuilder = new TagBuilder("a"); 
    tagBuilder.Attributes.Add("href",href); 
    tagBuilder.Attributes.Add("title", title); 
    htmlHelper.ViewContext.Writer.Write(tagBuilder 
            .ToString(TagRenderMode.StartTag)); 
    return new MvcAnchor(htmlHelper.ViewContext); 
} 

und unserer Ansicht nach:

@{ 
    using (Html.BeginLink("http://stackoverflow.com", "The Worlds Best Q&A site")) 
    { 
     @Html.Raw("StackOverflow - Because we really do care") 
    } 
} 

, die das Ergebnis liefert:

<a href="http://stackoverflow.com" title="The Worlds Best Q&amp;A site"> 
    StackOverflow - Because we really do care</a> 
+2

das ist schön. Du hast mir gerade einen halben Tag gerettet :)) –

2

In ihrer einfachsten Ebene so etwas wie dies tun würde, es

public static MvcHtmlString SomeLink(this HtmlHelper htmlHelper, string href, string  title, string content) 
    { 
     var urlHelper = ((Controller)htmlHelper.ViewContext.Controller).Url; 
     //var url = urlHelper.Action(actionName, controllerName, routeValues); 

     var someLink = new TagBuilder("a"); 
     someLink.MergeAttribute("href", href); 
     someLink.InnerHtml = content; 

     return new MvcHtmlString(someLink.ToString()); 
    } 
8

Es gibt auch eine andere Art und Weise , ohne Einwegtrick. Es ist weniger Arbeit, ideal für kleine Helfer. Ich antwortete ähnliche Frage, und will nicht alles kopieren, aber hier ist ein kurzes Beispiel:

@helper Paragraph(string cssClass, Func<object, object> markup) { 
    <p class="@cssClass">@markup.DynamicInvoke(this.ViewContext)</p> 
} 

Verwendung dieser Helfer wie folgt aussieht:

@Paragraph("highlited", 
    @<text> 
     Look, a @Html.ActionLink("link", "index") 
    </text> 
) 

Meine volle Antwort auf die anderen ähnliche Frage here.