Verwenden von MVC HtmlHelper-Erweiterungen von deklarativen Ansichten von Razor

Ich habe versucht, einen deklarativen Razor-Helper in meinem App_Code-Ordner für ein MVC 3 RTM-Projekt zu erstellen.

Das Problem, auf das ich stieß, war, dass die MVC HtmlHelper Erweiterungen, wie ActionLink, nicht verfügbar sind. Dies liegt daran, dass die kompilierten Helfer von System.Web.WebPages.HelperPage sind und eine Html Eigenschaft vom Typ System.Web.WebPages.HtmlHelper statt von System.Web.WebPages.HtmlHelper System.Web.Mvc.HtmlHelper .

Ein Beispiel für die Art von Fehler, die ich bekam, ist:

‘System.Web.Mvc.HtmlHelper’ enthält keine Definition für ‘ActionLink’ und es wurde keine Erweiterungsmethode ‘ActionLink’ gefunden, die ein erstes Argument vom Typ ‘System.Web.Mvc.HtmlHelper’ akzeptiert (fehlt eine using-Direktive) oder eine Assembly-Referenz?)

Meine einzige Lösung war, meine eigene HelperPage zu erstellen und die Html-Eigenschaft zu überschreiben:

 using System.Web.WebPages; public class HelperPage : System.Web.WebPages.HelperPage { // Workaround - exposes the MVC HtmlHelper instead of the normal helper public static new HtmlHelper Html { get { return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html; } } } 

Ich muss dann am Anfang jedes Helfers schreiben:

 @inherits FunnelWeb.Web.App_Code.HelperPage @using System.Web.Mvc @using System.Web.Mvc.Html @helper DoSomething() { @Html.ActionLink("Index", "Home") } 

Soll es in MVC 3 so schwer sein, oder mache ich etwas falsch?

Marcind Sie einen Blick auf Marcind Antwort auf diese Frage. Es besteht eine Einschränkung beim App_Code deklarativer Ansichten in den Ordner ” App_Code “.

Putting your helpers in App_Code funktioniert, hat aber bestimmte Einschränkungen, die sich auf bestimmte MVC-Szenarien auswirken (zum Beispiel: kein Zugriff auf Standard-MVC-Html-Helfer)

Ich habe eine Erweiterungsmethode für den WebPages-Helfer erstellt, damit ich auf den Seitenhelfer zugreifen kann.

 public static HtmlHelper GetPageHelper(this System.Web.WebPages.Html.HtmlHelper html) { return ((System.Web.Mvc.WebViewPage) WebPageContext.Current.Page).Html; } 

Omar hat hier die richtige Antwort, aber ich wollte etwas hinzufügen (fühlen Sie sich frei, Omars Antwort als Antwort zu markieren).

Wir waren uns dessen in Version 1 bewusst und konnten keine großartige Lösung für das Produkt finden, aber David Ebbo (ein Architekt des ASP.Net-Teams) veröffentlichte ein Beispiel für einen Visual Studio Code Generator, der im Grunde eine erste Erkundung von die Art von Ideen, die wir betrachten, um dies richtig funktionieren zu lassen: http://blogs.msdn.com/b/davidebb/archive/2010/10/27/turn-your-razor-helpers-into-reusable-libraries .aspx

Probieren Sie das aus und sehen Sie, was Sie denken! Lassen Sie David wissen, ob Sie Kommentare haben, indem Sie auf seinem Blog posten.

Ähnlich wie bei @Jakes antworten:

 public static class MvcIntrinsics { public static System.Web.Mvc.HtmlHelper Html { get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html; } } public static System.Web.Mvc.AjaxHelper Ajax { get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Ajax; } } public static System.Web.Mvc.UrlHelper Url { get { return ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Url; } } } 

Verwendung:

 @MvcIntrinsics.Html.Raw("test") 

Quelle: Dino Esposito – Programmierung von Microsoft ASP.NET MVC

Eine alternative Lösung:

Fügen Sie dies über Ihrer Rasierer-Hilfsdatei hinzu:

 @functions { public static System.Web.Mvc.HtmlHelper HHtml = ((System.Web.Mvc.WebViewPage)WebPageContext.Current.Page).Html; } 

dann nenne es so:

 @HHtml.ActionLink("actionname") 

Für die Suchenden habe ich den gleichen Fehler beim Erstellen von MVC-Ansichten als Teil einer classnbibliothek (für die Wiederverwendung von Komponenten) erhalten. Die Lösung, auf die oben teilweise eingegangen wurde, bestand darin, die folgenden using-statementen am Anfang der .cshtml-Datei hinzuzufügen:

 @using System.Web.Mvc @using System.Web.Mvc.Html 

Keine weiteren Arbeiten notwendig.

Meine Vorgehensweise besteht darin, die Seite einfach als Parameter an die Hilfsmethode zu übergeben. In deinem Beispiel wäre es also:

 @helper DoSomething(WebViewPage page) { @page.Html.ActionLink("Index", "Home") } 

Dann in Ihrer Razor-Ansicht, wo Sie es brauchen, nennen Sie es so:

 @YourHelperFilename.DoSomething(this) 

Html Sie dies sofort tun, erhalten Sie Zugriff auf Seiteneigenschaften wie Html oder Html , die Sie normalerweise haben (und damit die HtmlHelper Erweiterungen).

Als zusätzlichen Vorteil (wenn Sie dies benötigen) erhalten Sie auch Zugriff auf Instanzeigenschaften wie die ViewData der Seite.

Ich weiß, dass es bei MVC 3 einige Intellisense-Probleme gibt. Ich denke, die Helfer funktionieren auch dann, wenn Sie den Namespace in web.config festgelegt haben.

MVC 3 RTM wurde gerade veröffentlicht, verwenden Sie dies oder eine Beta?

Sieht aus wie die ASP.NET MVC dieses Problem in VS 2013 behoben hat. Siehe diesen Beitrag http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/3670180-support-helper-extensionmethod-this- htmlhelper-ht