tag sintaxis page net mvc asp c# asp.net asp.net-mvc asp.net-mvc-4 razor

c# - page - sintaxis razor mvc 5



¿Por qué no se encuentra el método de extensión en MVC4 Razor View? (4)

Cree su proyecto antes de agregar su espacio de nombres personalizado para las extensiones de su Vista.

Dado el siguiente método de extensión de cadena

namespace JHS.ExtensionMethods { public static class StringExtensions { public static string ToUSAPhone(this String str) { return String.Format("{0:(###) ###-####}", Double.Parse(str)); } } }

Se agregó una instrucción @using a la vista Razor MVC4

@using JHS.ExtensionMethods;

y el siguiente valor de cadena llama al método de extensión

@Model.producer.phone.ToUSAPhone()

lo que resulta en el siguiente error

''string'' does not contain a definition for ''ToUSAPhone''

También intenté colocar el espacio de nombres en el archivo web.config de la carpeta / Vistas y recibo el mismo error.

<pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> <add namespace="System.Web.Mvc" /> <add namespace="System.Web.Mvc.Ajax" /> <add namespace="System.Web.Mvc.Html" /> <add namespace="System.Web.Optimization"/> <add namespace="System.Web.Routing" /> <add namespace="JHS.ExtensionMethods"/> </namespaces> </pages>

He verificado que el método de extensión funciona al poner la misma llamada en una clase de C #

string test=producer.phone.ToUSAPhone();

Parece que la referencia al método de extensión no está disponible en la vista MVC4 Razor, pero no puedo entender por qué.


Esto sucede si el tipo en el que está intentando usar el método de extensión es en realidad dynamic . Verifique si CSharp RuntimeBinder genera la excepción. Si es así, puede usar el método como método estático común o de jardín:

@StringExtensions.ToUSAPhone(Model.producer.phone)

O puedes convertir el valor en una cadena:

@(((string)Model.producer.phone).ToUSAPhone())

Según Eric Lippert (anteriormente de MSFT):

La razón detrás del hecho de que la dinámica no admite tipos de extensión es porque en los métodos de extensión de código no dinámicos regulares se realiza una búsqueda completa de todas las clases conocidas por el compilador para una clase estática que tiene un método de extensión que coincide. La búsqueda se realiza en orden según el anidamiento del espacio de nombres y las directivas de "uso" disponibles en cada espacio de nombres.

Eso significa que para que la invocación de un método de extensión dinámica se resuelva correctamente, de alguna manera, el DLR debe saber en tiempo de ejecución qué eran todos los anidamientos de espacio de nombres y las directivas de "uso" en su código fuente. No hay ningún mecanismo útil para codificar toda esa información en el sitio de la llamada.


No es solo si el tipo al que está llamando el método de extensión es dinámico, sino si algo en la expresión es dinámico y no se convierte.

Por ejemplo, esto es claramente dinámico:

@ViewBag.ToJSON()

Pero primero pensé que la respuesta de Mike no se aplicaba a mí porque estaba haciendo esto:

@(ViewBag.UserProfile.GetJSONProfile().ToJSON())

donde ToJSON() es mi método de extensión y GetJSONProfile() simplemente devuelve el object .

Solo estaba espaciándome y siendo estúpido, pero quería mencionar esto.


Puede haber otra razón trivial para esto y me pasó a mí.

El archivo en el que creé mi extensión tenía "Contenido" como valor para la propiedad Build Action en el panel de propiedades del archivo VS.

Cambiarlo a "Compilar" inmediatamente solucionó el problema, naturalmente ...