web-dev-qa-db-fra.com

ASP.NET MVC: Assistants HTML personnalisés dans Razor

J'ai des difficultés avec les Helpers Html lorsqu'ils sont utilisés avec Razor. Ces aides ont bien fonctionné dans MVC 2 avec le moteur d'affichage de formulaire Web. Mais pas au rasoir. L'erreur que j'obtiens à l'exécution est:

Compiler Error Message: CS1502: The best overloaded method match for 'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)' has some invalid arguments

Source Error:


Line 1:  @using Wingspan.Web.Mvc;
Line 2:  @Html.IncrementalMenu(MenuBlock.Site)

L'extension de la sortie Show Compiler détaillée révèle:

d:\...\Views\Shared\MenuTop.cshtml(2,1): error CS1502: The best overloaded method match for 'System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)' has some invalid arguments
d:\...\Views\Shared\MenuTop.cshtml(2,7): error CS1503: Argument 1: cannot convert from 'void' to 'System.Web.WebPages.HelperResult'

Cela m'indique que le rasoir n'aime pas mon aide, IncrementalMenu, renvoyant void (qui fonctionne très bien dans les vues du moteur de formulaire Web MVC 2).

Je ne reçois aucune erreur au moment de la compilation, bien que la ligne de code (@ Html.IncrementalMenu (...)) soit soulignée en rouge avec le message suivant:

Cannot implicitly convert type 'void' to 'object'

IncrementalMenu se trouve dans l'espace de noms Wingspan.Web.Mvc. Sa signature est la suivante:

public static void IncrementalMenu(this HtmlHelper html, MenuBlock menuBlock)
{
    // Uses an HtmlTextWriter to render a menu from the sitemap
}

Je suis épaté si je sais ce qui ne va pas ...

PS:

Le paramètre MenuBlock est juste une énumération qui identifie le rendu du menu. Ne vous attardez pas sur ce point car c'est très bien.

63
awrigley

Vous pouvez appeler votre assistant comme ceci:

@{ Html.IncrementalMenu(MenuBlock.Site); }

Syntaxe WebForms

<% Html.IncrementalMenu(MenuBlock.Site); %>

Vous appelez simplement votre méthode et la valeur de retour (s'il y en a) est ignorée.

Un code comme celui-ci attend une valeur de retour et écrit la valeur de retour dans le flux html:

@Html.YourHelper()

Syntaxe des formulaires Web:

<%: Html.YourHelper() %>

Le même, si la valeur du résultat! = IHtmlString:

<%= Server.HtmlEncode(Html.YourHelper()) %>
85
GvS

Addenda:

Vous pouvez obtenir la même erreur ou une erreur similaire avec @ Html.RenderPartial. Dans ce cas, cela est dû au fait que RenderPartial est rendu directement à la réponse, il ne s'agit donc pas d'une chaîne et doit être codé à l'intérieur d'un "bloc de code Razor":

@{
   Html.RenderPartial(...);
}

Je soupçonne que c'est l'une des raisons pour lesquelles Microsoft a inclus dans ASP.NET MVC le nouveau Html.Partial. Comme Html.Partial retourne une chaîne, il est OK d'écrire:

@Html.Partial

Ce qui est beaucoup mieux. Étant donné que l'un des objectifs déclarés de Razor est d'être facile à regarder, c'est très probablement vrai.

Cela me permet également, au moins, de me sentir plus à l'aise. Je sais ce qu'est le retour d'une chaîne, je le fais tout le temps. Mais "revenir à la réponse" nécessite quelques cycles cérébraux de plus à chaque fois que je le pense.

Et cela correspond au vieil adage selon lequel Microsoft obtient enfin ses produits dans la version 3. EG, Access 97.

Ce qui est une comparaison déprimante. Parce qu'ils ont foiré les choses dans la version 4, c'est-à-dire Access 2000 ...

49
awrigley

Votre assistant HTML doit retourner MvcHtmlString qui représente le html afin de fonctionner correctement avec Razor (et d'autres moteurs de vue qui ne sont pas WebFormsViewEngine)

public static MvcHtmlString Label(this HtmlHelper html, string expression)
{
    return MvcHtmlString.Create("<label>" + expression + "</label>");
}
22
Atanas Korchev