Question

Je suis en train d'écrire mon propre extenstion HtmlHelper pour ASP.NET MVC:

public static string CreateDialogLink (this HtmlHelper htmlHelper, string linkText, 
                                      string contentPath)
        {
            // fix up content path if the user supplied a path beginning with '~'
            contentPath = Url.Content(contentPath);  // doesn't work (see below for why)

            // create the link and return it
            // .....
        };

Si je ne parviens pas à accéder est tryin à partir UrlHelper dans les définition de mon HtmlHelper. Le problème est que la façon dont vous accédez normalement HtmlHelper (via Html.MethodName(...)) est via une propriété sur la vue. Ce n'est pas disponible pour moi évidemment de ma propre classe d'extension.

Ceci est le code source réelle pour MVC ViewMasterPage (à partir de bêta) -. Html qui définit et Url

public class ViewMasterPage : MasterPage
    {
        public ViewMasterPage();

        public AjaxHelper Ajax { get; }
        public HtmlHelper Html { get; }
        public object Model { get; }
        public TempDataDictionary TempData { get; }
        public UrlHelper Url { get; }
        public ViewContext ViewContext { get; }
        public ViewDataDictionary ViewData { get; }
        public HtmlTextWriter Writer { get; }
    }

Je veux être en mesure d'accéder à ces propriétés à l'intérieur d'un HtmlHelper.

Le meilleur que je suis venu avec c'est (insérer au début de la méthode CreateDialogLink)

HtmlHelper Html = new HtmlHelper(htmlHelper.ViewContext, htmlHelper.ViewDataContainer);
UrlHelper Url = new UrlHelper(htmlHelper.ViewContext.RequestContext);

Suis-je manque un autre moyen d'accéder aux instances existantes et <=> <=> - ou dois-je vraiment besoin de créer un nouveau? Je suis sûr qu'il n'y a pas de frais généraux, mais je préfère utiliser les pré-existantes si je peux.

Était-ce utile?

La solution

Avant de poser cette question, je l'avais regardé une partie du code source MVC, mais évidemment je manqué ce qui est de savoir comment ils le font pour l'aide d'images.

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "The return value is not a regular URL since it may contain ~/ ASP.NET-specific characters")]
        public static string Image(this HtmlHelper helper, string imageRelativeUrl, string alt, IDictionary<string, object> htmlAttributes) {
            if (String.IsNullOrEmpty(imageRelativeUrl)) {
                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "imageRelativeUrl");
            }

            UrlHelper url = new UrlHelper(helper.ViewContext);
            string imageUrl = url.Content(imageRelativeUrl);
            return Image(imageUrl, alt, htmlAttributes).ToString(TagRenderMode.SelfClosing);
        }

On dirait que instanciation d'une nouvelle approche est UrlHelper correcte après tout. Des thats assez bon pour moi.


Mise à jour: code RTM de ASP.NET MVC est légèrement différent comme indiqué dans les commentaires.

Fichier: MVC \ src \ MvcFutures \ Mvc \ ImageExtensions.cs

 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "1#", Justification = "The return value is not a regular URL since it may contain ~/ ASP.NET-specific characters")]
        public static string Image(this HtmlHelper helper, string imageRelativeUrl, string alt, IDictionary<string, object> htmlAttributes) {
            if (String.IsNullOrEmpty(imageRelativeUrl)) {
                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "imageRelativeUrl");
            }

            UrlHelper url = new UrlHelper(helper.ViewContext.RequestContext);
            string imageUrl = url.Content(imageRelativeUrl);
            return Image(imageUrl, alt, htmlAttributes).ToString(TagRenderMode.SelfClosing);
        }

Autres conseils

Je fait face à un problème similaire et décidé qu'il serait plus facile d'appeler juste le UrlHelper dans la vue et de passer la sortie à mon extension HtmlHelper. Dans votre cas, il ressemblerait à ceci:

<%= Html.CreateDialogLink( "text", Url.Content( "~/...path.to.content" ) ) %>

Si vous voulez accéder aux méthodes d'extension sur le HtmlHelper existant qui est passé dans votre classe, vous ne devriez avoir besoin d'importer System.Web.Mvc.Html dans votre fichier de code source et vous aurez accès à eux (c'est là les classes d'extension sont définies). Si vous voulez un UrlHelper, vous devrez instancier que le HtmlHelper que vous obtenez ne pas une poignée pour le ViewPage qu'il vient.

Si vous devez créer un UrlHelper dans une classe utilitaire, vous pouvez faire ce qui suit:

string url = "~ / content / images / foo.jpg";

  var urlHelper = new UrlHelper(new RequestContext(
                  new HttpContextWrapper(HttpContext.Current), 
                  new RouteData()), RouteTable.Routes);

  string absoluteUrl = urlHelper.Content(url);

Cela vous permet d'utiliser le routage ou « ~ extension » en dehors d'un contexte MVC.

Eh bien, vous pouvez toujours passer l'instance de la page à la méthode d'extension. Je pense que c'est une bien meilleure façon de le faire que de créer de nouvelles instances dans votre méthode.

Vous pouvez également définir cette méthode sur une classe qui dérive de MasterPage / ViewMasterPage puis tirer la page de cela. De cette façon, vous avez accès à toutes les propriétés de l'instance et ne pas les faire passer.

scroll top