为什么我不能在Razor WebGrid中的委托中使用我的扩展方法

时间:2013-03-22 21:37:21

标签: c# asp.net-mvc webgrid

我正在使用MVC 3引入的WebGrid,但在传递format param的委托时无法应用我自己的扩展方法。

使用:

Grid.Column("MyProperty", "MyProperty", 
format: @<span class="something">@item.MyProperty.MyExtensionMethodForString()</span>)

我得到了

ERROR: 'string' does not contain a definition for 'MyExtensionMethodForString'

我尝试过施法,但没有利用

Grid.Column("MyProperty", "MyProperty", 
format: @<span class="something">@((string)(item.MyProperty).MyExtensionMethodForString())</span>)

如果我使用标准方法,它可以工作:

Grid.Column("MyProperty", "MyProperty", 
format: @<span class="something">@(Utils.MyExtensionMethodForString(item.MyProperty))</span>)

我也尝试将扩展名放在同一名称空间中,没有结果。

如何使用我心爱的扩展程序?

编辑:命名空间本身不是问题,扩展名可用于所有视图和类的命名空间,我可以在同一视图中使用它而没有问题。问题是在委托中使用它时。

3 个答案:

答案 0 :(得分:2)

这不是WebGrid或Razor的限制。这是C#dynamic类型的限制。您不能在动态上使用扩展方法。格式助手将Func<dynamic, object>作为参数,因此item参数是动态类型。

几年前我wrote about this exact issue

答案 1 :(得分:1)

这对我来说很好。静态类:

public static class TestExtensions
{
    public static string Foo(this HtmlHelper html, Func<object, HelperResult> func)
    {
        return func(null).ToHtmlString();
    }

    public static string MyStringExtension(this string s)
    {
        return s.ToUpper();
    }
}

Index.cshtml:

@using MvcApplication1.Controllers

@Html.Foo(@<text>@Html.Raw("Hello")</text>)

页面打印出来:

  

您好

但是,这个版本的Index.cshtml:

@using MvcApplication1.Controllers

@Html.Foo(@<text>@("Hello".MyStringExtension())</text>)

打印出错误信息:

  

CS1061:'string'不包含'MyStringExtension'的定义,并且没有可以找到接受类型'string'的第一个参数的扩展方法'MyStringExtension'(你是否缺少using指令或汇编引用?)< / p>

所以我怀疑Jon是正确的,这是Razor的限制。 (为什么它适用于HtmlHelper让我有点神秘)

答案 2 :(得分:0)

通过研究为什么以下行引发同样的错误来找到这个问题:

@a.GetAttribute<ActionLabelAttribute>().ActionLabel

原来可以通过将这一行括在括号中来轻松纠正,如下所示:

@(a.GetAttribute<ActionLabelAttribute>().ActionLabel)

注意:GetAttribute扩展方法来自here