为什么在 MVC4 剃刀视图中找不到扩展方法

本文关键字:找不到 扩展 方法 视图 MVC4 剃刀 为什么 | 更新日期: 2023-09-27 18:34:39

给定以下字符串扩展方法

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

@using语句已添加到 MVC4 Razor 视图中

@using JHS.ExtensionMethods;

和以下字符串值调用扩展方法

@Model.producer.phone.ToUSAPhone()

这会导致以下错误

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

我还尝试将命名空间放在/Views 文件夹的 web.config 中,并收到相同的错误。

<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>

我已经通过将相同的调用放入 C# 类来验证扩展方法的工作原理

string test=producer.phone.ToUSAPhone();

似乎在MVC4 Razor视图中看不到对扩展方法的引用,但我无法弄清楚为什么?

为什么在 MVC4 剃刀视图中找不到扩展方法

如果您尝试在其上使用扩展方法的类型实际上是dynamic,则会发生这种情况。检查异常是否由 CSharp 运行时绑定器生成。如果是这样,则可以将该方法用作常用方法或花园静态方法:

@StringExtensions.ToUSAPhone(Model.producer.phone)

或者,您可以将值强制转换为字符串:

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

根据Eric Lippert(前MSFT(的说法:

动态不支持扩展背后的原因 类型是因为在常规的非动态代码扩展方法中工作 通过对编译器已知的所有类进行全面搜索 具有匹配的扩展方法的静态类。搜索进行 根据命名空间嵌套和可用的"使用"按顺序排列 每个命名空间中的指令。

这意味着为了获得动态扩展方法调用 正确解决,不知何故,DLR 必须在运行时知道所有 命名空间嵌套和"using"指令在您的源代码中 法典。没有方便的机制来编码所有这些信息 进入呼叫站点。

这不仅仅是您调用扩展方法的类型是否是动态的,而是表达式中的任何内容是否是动态的并且不是强制转换。

例如,这显然是动态的:

@ViewBag.ToJSON()

但我首先认为迈克的回答不适用于我,因为我正在这样做:

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

其中ToJSON()是我的扩展方法,GetJSONProfile()只返回object.

我只是隔开,很愚蠢,但想提一下。

在将扩展的自定义命名空间添加到视图之前生成项目。

这可能还有另一个微不足道的原因,它发生在我身上。

我在其中创建扩展的文件将"内容"作为 VS 文件属性窗格中生成操作属性的值。

将其切换到"编译"立即解决了问题,自然...

我在相同的错误消息中遇到了完全相同的问题,但在我的情况下,以某种奇怪的方式,我通过输入";"来修复它

那么是什么

@{var subti = item.subtitle.Truncate(18)}

用 ;

@{var subti = item.subtitle.Truncate(18);}

这也许可以帮助某人