2012-02-05 12 views
5

Ho troppi metodi di utilità di testo, come MakeShortText(string text, int length), RemoveTags(string text), TimeAgo(DateTime date) e altro. Voglio accedervi da aiutante separato come nel prossimo esempio:Creazione di helper personalizzato disponibile nelle viste

@Text().MakeShortText(Model.Text, 10) 

E 'possibile creare tale estensione? O devo rendere l'estensione per HtmlHelper in questo modo:

@Html.Text().MaksShortText(Model.Text, 10) 

?

risposta

10

Si potrebbe iniziare definendo una consuetudine TextHelper:

public class TextHelper 
{ 
    public TextHelper(ViewContext viewContext) 
    { 
     ViewContext = viewContext; 
    } 

    public ViewContext ViewContext { get; private set; } 
} 

e quindi avere tutti i vostri metodi siano i metodi di estensione di questo TextHelper:

public static class TextHelperExtensions 
{ 
    public static IHtmlString MakeShortText(
     this TextHelper textHelper, 
     string text, 
     int value 
    ) 
    { 
     ... 
    } 
} 

allora si potrebbe definire una pagina web personalizzata:

public abstract class MyWebViewPage<T> : WebViewPage<T> 
{ 
    public override void InitHelpers() 
    { 
     base.InitHelpers(); 
     Text = new TextHelper(ViewContext); 
    } 

    public TextHelper Text { get; private set; } 
} 

quindi nel tuo ~/Views/web.config (non in ~/web.config) configurare questa pagina web personalizzata come pagina di base per i vostri punti di vista Razor utilizzando l'attributo pageBaseType:

<pages pageBaseType="AppName.Web.Mvc.MyWebViewPage"> 
    <namespaces> 
     <add namespace="System.Web.Mvc" /> 
     <add namespace="System.Web.Mvc.Ajax" /> 
     <add namespace="System.Web.Mvc.Html" /> 
     <add namespace="System.Web.Routing" /> 
    </namespaces> 
</pages> 

e poi nel vostro punto di vista si sarà in grado di utilizzare:

@Text.MakeShortText(Model.Text, 10) 

E se si voleva utilizzare la seguente sintassi, come mostrato nella tua domanda:

@Text().MakeShortText(Model.Text, 10) 

semplicemente modificare il c motore di visualizzazione di ustom in modo che Text non sia una proprietà ma un metodo che restituirà un'istanza di TextHelper. O anche restituire l'istanza HtmlHelper in modo che non c'è bisogno di spostare i metodi di estensione esistenti per TextHelper:

public abstract class MyWebViewPage<T> : WebViewPage<T> 
{ 
    public HtmlHelper Text() 
    { 
     return Html; 
    } 
} 

La seconda sintassi è anche possibile:

@Html.Text().MaksShortText(Model.Text, 10) 

definire semplicemente un costume Estensione Text() per la classe HtmlHelper:

public static class HtmlExtensions 
{ 
    public static TextHelper Text(this HtmlHelper htmlHelper) 
    { 
     return new TextHelper(htmlHelper.ViewContext); 
    } 
} 

e quindi nello stesso modo in cui nel primo caso i metodi personalizzati sarebbero i metodi di estensione di questa classe TextHelper.

+0

Grazie per la risposta così accurata e dettagliata. È stato molto utile Ma non capisco perché ho bisogno del parametro ViewContext nel ctor di TextHelper? –

+1

@EvgenyLevin, in modo da avere accesso a 'HttpContext' nei metodi di estensione personalizzati. Cose come Request, Response, Session, RouteData, ... sono normalmente utili in un helper. Puoi anche chiamare altri metodi di estensione per esempio, ad esempio la classe HtmlHelper come TextBoxFor, ... Ovviamente potresti rimuoverlo se non ne hai bisogno. –

+1

@DarinDimitrov bella risposta! +1 – dknaack

Problemi correlati