J'essaie d'écrire une aide dans Razor qui ressemble à ce qui suit:
@helper DoSomething<T, U>(Expression<Func<T, U>> expr) where T : class
Malheureusement, l'analyseur pense que <T
c'est le début d'un élément HTML et je me retrouve avec une erreur de syntaxe. Est-il possible de créer un assistant avec Razor qui est une méthode générique? Si oui, quelle est la syntaxe?
asp.net-mvc
generics
asp.net-mvc-3
razor
mkedobbs
la source
la source
static
, à moins que les détails d'implémentation ne l'interdisent; La raison en est, est-ce qu'on pourrait utiliser des assistants d'extension génériques :@helper Foo<T>(this T o) where T : IBar { }
Réponses:
Non, ce n'est pas possible. Vous pouvez plutôt écrire un assistant HTML normal.
puis:
ou si vous ciblez le modèle comme premier argument générique:
ce qui vous permettra de l'invoquer comme ceci (en supposant bien sûr que votre vue est fortement typée, mais c'est une hypothèse sûre car toutes les vues doivent être fortement typées de toute façon :-)):
la source
Cela est possible à l'intérieur d'un fichier d'aide avec la
@functions
syntaxe, mais si vous voulez la lisibilité de style rasoir à laquelle vous faites référence, vous devrez également appeler un assistant régulier pour faire l'ajustement et la finition HTML.Notez que les fonctions d'un fichier Helper sont statiques, vous devrez donc toujours transmettre l'instance HtmlHelper de la page si vous aviez l'intention d'utiliser ses méthodes.
par exemple Views \ MyView.cshtml:
App_Code \ MyHelper.cshtml:
la source
System.Web.WebPages.Html.HtmlHelper
plutôt queSystem.Web.Mvc.HtmlHelper
. Il y a de fortes chances que laWebPages
version ne vous convienne pas, car la plupart des méthodes d'extension sont écrites contreSystem.Web.Mvc.HtmlHelper
. De plus, il n'y a pas deUrl
propriété, etUrlHelper
nécessite uneRequestContext
qui n'est pas disponible dans laWebPages
version. Dans l'ensemble, vous devrez probablement passer dans leMvc
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` dansApp_Code
.DoSomething
doit être statique, afin que vous puissiez appeler@MyHelper.DoSomething(..)
dans votre vue. Si vous le rendez non statique, vous devez créer une instance deMyHelper
first.Dans tous les cas, le
TModel
sera le même (le modèle déclaré pour la vue), et dans mon cas, leTValue
sera le même, j'ai donc pu déclarer le type d'argument Expression:Si vos champs de modèle sont tous
string
, vous pouvez les remplacerMyClass
parstring
.Ce n'est peut-être pas mal de définir deux ou trois helpers avec le
TValue
défini, mais si vous en avez plus qui génèreraient du code laid, je n'ai pas vraiment trouvé de bonne solution. J'ai essayé d'envelopper@helper
une fonction que j'ai placée dans le@functions {}
bloc, mais je ne l'ai jamais fait fonctionner dans cette voie.la source
TModel
vous le savez probablement à l'avance.si votre principal problème est d'obtenir la valeur d'attribut de nom pour la liaison à l'aide de l'expression lambda
@Html.TextBoxFor(x => x.MyPoperty)
, et si votre composant a des balises html très complexes et doit être implémenté sur razor helper, alors pourquoi ne pas simplement créer une méthode d'extensionHtmlHelper<TModel>
pour résoudre le nom de la liaison:votre aide-rasoir devrait être comme d'habitude:
alors ici vous pouvez l'utiliser
la source
@Htm.IdFor
mais vous avez besoin d'un processus supplémentaire pour le convertir en string (.ToHtmlString()
) où l'assistant nécessite une chaîne