wake-up-neo.com

Verwenden der MVC HtmlHelper-Erweiterungen aus deklarativen Ansichten von Razor

Ich habe versucht, einen deklarativen Razor-Helfer 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 stammen und obwohl sie eine Html-Eigenschaft verfügbar machen, deren Typ System.Web.WebPages.HtmlHelper und nicht System.Web.Mvc.HtmlHelper ist.

Ein Beispiel für die Art von Fehlern, die ich erhielt, ist:

"System.Web.Mvc.HtmlHelper" führt keine enthalten eine Definition für 'ActionLink' und keine Erweiterungsmethode 'ActionLink' Akzeptieren eines ersten Arguments vom Typ 'System.Web.Mvc.HtmlHelper' könnte .__ sein. gefunden (fehlt eine using Direktive oder eine Assemblyreferenz?)

Meine einzige Lösung bestand darin, 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 oben auf jeden Helfer folgendes 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?

121
Paul Stovell

Werfen Sie einen Blick auf Marcinds Antwort auf diese Frage. Was Sie erleben, ist eine Einschränkung der Platzierung deklarativer Ansichten im Ordner App_Code.

Das Einfügen Ihrer Helfer in App_Code funktioniert hat aber gewisse Einschränkungen, die Auswirkungen auf bestimmte MVC-Szenarien (für Beispiel: kein Zugriff auf Standard-MVC Html. -Hilfegeräte)

42
Omar

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;
}
38
Jake Hoffner

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

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 aus dem ASP.Net-Team) hat ein Beispiel für einen Visual Studio Code Generator veröffentlicht, der im Wesentlichen eine erste Erkundung von ist Die Art von Ideen, die wir prüfen, damit dies richtig funktioniert: http://blogs.msdn.com/b/davidebb/archive/2010/10/27/turn-your-razor-helpers-into-reusable -libraries.aspx

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

11

Ähnlich wie bei @Jakes Antwort:

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

}

Verwendungszweck:

@MvcIntrinsics.Html.Raw("test")

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

9
Greg Gum

Eine alternative Lösung:

Fügen Sie dies über Ihrer Rasiermesser-Helfer-Datei hinzu:

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

dann nennen Sie es so:

@HHtml.ActionLink("actionname")
7
Alex

Zum Nutzen der Sucher habe ich den gleichen Fehler erhalten, als ich MVC-Ansichten als Teil einer Klassenbibliothek (zur Wiederverwendung von Komponenten) erstellt habe. Die oben angedeutete Lösung bestand darin, die folgenden using-Anweisungen oben in der CSHML-Datei hinzuzufügen:

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

Keine weiteren Arbeiten notwendig.

4
HockeyJ

Mein Ansatz dazu ist, die Seite einfach als Parameter an die Hilfsmethode zu übergeben. In Ihrem Beispiel wäre es also:

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

Dann in der Rasiermesser-Ansicht, wo Sie es brauchen, nennen Sie es so:

@YourHelperFilename.DoSomething(this)

Wenn Sie dies sofort tun, haben Sie Zugriff auf Seiteneigenschaften wie Html oder Url, die Sie normalerweise haben (und dadurch die HtmlHelper-Erweiterungen).

Als zusätzlicher Vorteil (falls erforderlich) erhalten Sie auch Zugriff auf Instanzeigenschaften wie ViewData der Seite.

3
Dejan

Sieht aus, als hätte der ASP.NET-MVC dieses Problem in VS 2013 behoben. Siehe diesen Beitrag http://aspnet.uservoice.com/forums/41201-asp-net-mvc/suggestions/3670180-support-helper-extensionmethod -this-htmlhelper-ht

0
Omar

Ich weiß, dass es einige Probleme mit MVC 3 von Intellisense gibt. Ich denke, die Helfer funktionieren auch, wenn Sie den Namespace in web.config eingestellt haben.

MVC 3 RTM wurde gerade veröffentlicht. Verwenden Sie dieses oder eine Beta? 

0
Lee Smith