Ich versuche, in Razor einen Helfer zu schreiben, der wie folgt aussieht:
@helper DoSomething<T, U>(Expression<Func<T, U>> expr) where T : class
Leider denkt der Parser, dass dies <T
der Anfang eines HTML-Elements ist und ich am Ende einen Syntaxfehler habe. Ist es möglich, mit Razor einen Helfer zu erstellen, der eine generische Methode ist? Wenn ja, wie lautet die Syntax?
asp.net-mvc
generics
asp.net-mvc-3
razor
mkedobbs
quelle
quelle
static
, es sei denn, Implementierungsdetails verbieten dies. Grund dafür ist, dass man generische Erweiterungshelfer verwenden könnte :@helper Foo<T>(this T o) where T : IBar { }
Antworten:
Nein das ist nicht möglich. Sie können stattdessen einen normalen HTML-Helfer schreiben.
und dann:
oder wenn Sie das Modell als erstes generisches Argument anvisieren:
Damit können Sie es so aufrufen (vorausgesetzt natürlich, dass Ihre Ansicht stark typisiert ist, aber das ist eine sichere Annahme, da alle Ansichten sowieso stark typisiert sein sollten :-)):
quelle
Dies ist in einer Hilfedatei mit der
@functions
Syntax möglich. Wenn Sie jedoch die Lesbarkeit im Rasiermesser-Stil wünschen, auf die Sie sich beziehen, müssen Sie auch einen regulären Helfer aufrufen, um die HTML-Anpassung und -Endung durchzuführen.Beachten Sie, dass die Funktionen in einer Hilfedatei statisch sind, sodass Sie die HtmlHelper-Instanz weiterhin von der Seite übergeben müssen, wenn Sie ihre Methoden verwenden möchten.
zB Views \ MyView.cshtml:
App_Code \ MyHelper.cshtml:
quelle
System.Web.WebPages.Html.HtmlHelper
stattSystem.Web.Mvc.HtmlHelper
. Es besteht eine hervorragende Chance, dass dieWebPages
Version nicht für Sie geeignet ist, da die meisten Erweiterungsmethoden dagegen geschrieben sindSystem.Web.Mvc.HtmlHelper
. Darüber hinaus gibt es keineUrl
Eigenschaft undUrlHelper
erfordert eine,RequestContext
die in derWebPages
Version nicht verfügbar ist . Alles in allem müssen Sie wahrscheinlich in der übergebenMvc
HtmlHelper
.{MyMvcProject}\App_Code`. It doesn't work as advertised when you place it elsewhere. The error *Cannot access non-static method 'TheThingToDo' in static context* disappears when you move
MyHelper.cshtml` in abgelegt werdenApp_Code
.DoSomething
sollte statisch sein, damit Sie@MyHelper.DoSomething(..)
in Ihrer Ansicht aufrufen können. Wenn Sie es nicht statisch machen, müssen SieMyHelper
zuerst eine Instanz von erstellen .In allen Fällen
TModel
ist derselbe derselbe (das für die Ansicht deklarierte Modell), und in meinem FallTValue
sollte derselbe derselbe sein, sodass ich den Argumenttyp des Ausdrucks deklarieren konnte:Wenn Ihr Modell Felder alle sind
string
, dann können Sie ersetzenMyClass
mitstring
.Es mag nicht schlecht sein, zwei oder drei Helfer mit den
TValue
definierten zu definieren, aber wenn Sie mehr haben, die hässlichen Code erzeugen würden, habe ich keine wirklich gute Lösung gefunden. Ich habe versucht, das@helper
von einer Funktion zu verpacken, die ich in den@functions {}
Block eingefügt habe, aber ich habe es nie dazu gebracht, diesen Pfad zu bearbeiten.quelle
TModel
, wissen Sie es wahrscheinlich im Voraus.wenn Ihr Hauptproblem ist , erhalten Namen scheint Lambda - Ausdruck Attributwert für die Bindung verwendet wie das
@Html.TextBoxFor(x => x.MyPoperty)
, und wenn Ihre Komponente sehr komplexe HTML - Tags mit und soll auf gestochen Helfern umgesetzt werden, warum dann nicht nur eine Erweiterung Methode erstellenHtmlHelper<TModel>
lösen die verbindlicher Name:Ihr Rasiererhelfer sollte wie gewohnt sein:
dann können Sie es hier verwenden
quelle
@Htm.IdFor
.ToHtmlString()