ASP.NET MVC:Auxiliares HTML personalizados no Razor
-
26-09-2019 - |
Pergunta
Estou tendo dificuldades com Html Helpers quando usados com o Razor.Esses ajudantes funcionaram bem no MVC 2 com o mecanismo de visualização de formulários da web.Mas não na navalha.O erro que recebo em tempo de execução é:
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)
A expansão de Mostrar saída detalhada do compilador revela:
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'
Isso indica para mim que o razor não gosta do meu ajudante, IncrementalMenu, retornando void (que funciona bem nas visualizações do mecanismo de formulário da web MVC 2).
Não recebo erros em tempo de compilação, embora a linha de código (@Html.IncrementalMenu(...)) esteja sublinhada em vermelho com a seguinte mensagem:
Cannot implicitly convert type 'void' to 'object'
IncrementalMenu está no namespace Wingspan.Web.Mvc.Sua assinatura é a seguinte:
public static void IncrementalMenu(this HtmlHelper html, MenuBlock menuBlock)
{
// Uses an HtmlTextWriter to render a menu from the sitemap
}
Estou surpreso se eu souber o que está errado...
PS:
O parâmetro MenuBlock é apenas um enum que identifica como o menu deve ser renderizado.Não se fixe nisso, pois está tudo bem.
Solução
Você pode ligar para seu ajudante assim:
@{ Html.IncrementalMenu(MenuBlock.Site); }
Sintaxe de WebForms
<% Html.IncrementalMenu(MenuBlock.Site); %>
Você apenas chama seu método e o valor de retorno (se houver) é ignorado.
Código como este espera um valor de retorno e grava o valor de retorno no fluxo HTML:
@Html.YourHelper()
Sintaxe dos formulários da web:
<%: Html.YourHelper() %>
O mesmo, se o valor do resultado! = IHtmlString:
<%= Server.HtmlEncode(Html.YourHelper()) %>
Outras dicas
Termo aditivo:
Você pode obter o mesmo erro ou semelhante com @Html.RenderPartial.Neste caso é devido ao fato de RenderPartial renderizar diretamente para o Response, portanto não é uma string e precisa ser codificado dentro de um "bloco de código Razor":
@{
Html.RenderPartial(...);
}
Suspeito que esse seja um dos motivos pelos quais a Microsoft incluiu no ASP.NET MVC o novo Html.Partial.Como Html.Partial retorna uma string, não há problema em escrever:
@Html.Partial
O que parece muito melhor.Dado que um dos objetivos declarados da Razor é ser agradável à vista, isso provavelmente é verdade.
Isso também me faz, pelo menos, me sentir mais confortável.Eu sei o que é retornar uma string, faço isso o tempo todo.Mas “retornar à Resposta” requer mais alguns ciclos cerebrais cada vez que penso nisso.
E isso se encaixa no velho ditado de que finalmente a Microsoft acerta seus produtos na versão 3.EX.: Acesso 97.
O que é uma comparação deprimente.Porque eles estragaram tudo na versão 4, ou seja, Access 2000...
Seu auxiliar HTML deve retornar MvcHtmlString que representa o html para funcionar corretamente com o Razor (e outros mecanismos de visualização que não são o WebFormsViewEngine)
public static MvcHtmlString Label(this HtmlHelper html, string expression)
{
return MvcHtmlString.Create("<label>" + expression + "</label>");
}