2012-02-05 10 views
5

Tengo demasiados métodos de utilidad de texto, como MakeShortText(string text, int length), RemoveTags(string text), TimeAgo(DateTime date) y otros. Quiero acceder a ellos desde ayudante separada como en el siguiente ejemplo:Crear ayuda personalizada disponible en las vistas

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

¿Es posible crear dicha extensión? O tengo que hacer una extensión para HtmlHelper de esta manera:

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

?

Respuesta

10

Se podría empezar por definir una costumbre TextHelper:

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

    public ViewContext ViewContext { get; private set; } 
} 

y luego tener todos sus métodos sean los métodos de extensión de este TextHelper:

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

A continuación, se puede definir una página web personalizada:

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

    public TextHelper Text { get; private set; } 
} 

luego en su ~/Views/web.config (no en ~/web.config) configurar esta página web personalizada como la página de base para sus puntos de vista de afeitar utilizando el atributo 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> 

y luego en sus puntos de vista usted será capaz de utilizar:

@Text.MakeShortText(Model.Text, 10) 

Y si desea utilizar la siguiente sintaxis como se muestra en su pregunta:

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

simplemente modificar el c ustom view engine para que Text no sea una propiedad sino un método que devolverá una instancia del TextHelper. O incluso devolver la instancia HtmlHelper de manera que no es necesario mover los métodos de extensión existentes para TextHelper:

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

La segunda sintaxis es también posible:

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

simplemente definir una costumbre Text() extensión para la clase HtmlHelper:

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

y luego de la misma manera que en el primer caso, tendría sus métodos personalizados como métodos de extensión de esta clase TextHelper.

+0

Gracias por su respuesta tan precisa y detallada. Fue muy útil. Pero no entiendo por qué necesito el parámetro ViewContext en el ctor de TextHelper. –

+1

@EvgenyLevin, para que tenga acceso al 'HttpContext' en sus métodos de extensión personalizados. Cosas como Request, Response, Session, RouteData, ... normalmente son útiles en un helper. También podría llamar a otros métodos de extensión en, por ejemplo, la clase HtmlHelper como TextBoxFor, ... Por supuesto, podría eliminarla si no la necesita. –

+1

@DarinDimitrov nice answer! +1 – dknaack

Cuestiones relacionadas