2012-05-17 19 views
18

Ho cercato ma non ho trovato nessuna soluzione rapida per un htmlhelper MVC 3 per creare un metodo wrapper. Quello che sto cercando è qualcosa di simile:MVC 3 htmlhelper metodo di estensione per avvolgere il contenuto

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

il risultato dovrebbe avere

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

Qualsiasi aiuto con questo.

+0

Stai chiedendo se è possibile fare qualcosa di simile: '@ Html.ActionLink (" Hello World "," MyAction ")'? – CallumVass

+0

No, non quello. So che esiste un tipo di approccio BeginForm() e EndForm() per gestire questo tipo di scenario, ma quando lo si fa su larga scala può causare un problema se si dimentica un tag di chiusura. – Sanj

+0

Non sono sicuro di sapere cosa intendi?Non useresti 'BeginForm' in questo scenario? Dovresti usare 'BeginForm' per creare un modulo, non un collegamento di ancoraggio. – CallumVass

risposta

42

Il modo in cui questo viene fatto con BeginForm è che il tipo di ritorno MvcForm impliments IDisposable in modo che quando viene utilizzato all'interno di un'istruzione using, il metodo di DisposeMvcForm scrive il tag di chiusura </form>.

È possibile scrivere un metodo di estensione che fa esattamente la stessa cosa.

Ecco uno che ho appena scritto per dimostrare.

Prima di tutto, il metodo di estensione:

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

Ed ecco il nostro nuovo tipo, MvcAnchor:

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

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

Nel vostro punto di vista ora si può fare:

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

Quale produce il risultato:

<a>Hello World</a> 

Espansione questo un po 'a che fare con il vostro requisito esatto:

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

e la nostra visione:

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

da cui si ricava il risultato:

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

questo è bellissimo. mi hai appena salvato mezza giornata :)) –

2

Al suo livello più semplice qualcosa di simile sarebbe farlo

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

C'è anche un altro modo , senza trucco usa e getta. È meno lavoro, ottimo per i piccoli aiutanti. Ho risposto domanda simile, e non voglio copiare tutto, ma ecco un breve esempio:

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

L'uso di questo aiuto si presenta così:

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

La mia risposta piena all'altra domanda simile here.

Problemi correlati