简体   繁体   English

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

[英]Why can't I use my extension method in a delegate in the Razor WebGrid

I'm using the MVC 3 introduced WebGrid, but can't can't apply my own extension methods when passing a delegate for the format param. 我正在使用MVC 3引入WebGrid,但在传递format参数的委托时不能应用我自己的扩展方法。

Using: 使用:

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

I got 我有

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

I've tried casting, not to avail 我试过铸造,但没有用

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

If I use an standard method, it works: 如果我使用标准方法,它的工作原理:

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

I've also tried to put the extension in the same namespace, with no results. 我也尝试将扩展名放在同一名称空间中,没有结果。

How can I use my beloved extensions? 我如何使用我心爱的扩展?

Edit : The namespace per se it's not the problem, the namespace where the extension is available for all the views and classes, and I can use it in the same view without problem. 编辑 :命名空间本身不是问题,扩展可用于所有视图和类的命名空间,我可以在同一视图中使用它而没有问题。 The problem is when using it in the delegate. 问题是在委托中使用它。

This is not a limitation of the WebGrid or Razor. 这不是WebGrid或Razor的限制。 It's a limitation of the C# dynamic type. 这是C# dynamic类型的限制。 You cannot use extension methods on dynamic. 您不能在动态上使用扩展方法。 The format helper takes a Func<dynamic, object> as an argument, so the item parameter is a dynamic type. 格式助手将Func<dynamic, object>作为参数,因此item参数是动态类型。

I wrote about this exact issue a couple of years ago. 几年前我写过这个问题

This works just fine for me. 这对我来说很好。 Static class: 静态类:

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: Index.cshtml:

@using MvcApplication1.Controllers

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

The page prints out: 页面打印出来:

Hello 你好

However, this version of the Index.cshtml: 但是,这个版本的Index.cshtml:

@using MvcApplication1.Controllers

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

Prints out your error message: 打印出您的错误消息:

CS1061: 'string' does not contain a definition for 'MyStringExtension' and no extension method 'MyStringExtension' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?) CS1061:'string'不包含'MyStringExtension'的定义,并且没有可以找到接受类型'string'的第一个参数的扩展方法'MyStringExtension'(你是否缺少using指令或汇编引用?)

So I suspect Jon was correct and this is a limitation with Razor. 所以我怀疑Jon是正确的,这是Razor的限制。 (why it works with HtmlHelper leaves me a bit mystified though) (为什么它与HtmlHelper一起工作让我有点神秘)

Found this SO question by way of researching why the following line was throwing the same error: 通过研究为什么以下行引发相同的错误,发现了这个问题:

@a.GetAttribute<ActionLabelAttribute>().ActionLabel

Turns out it could easily be corrected by enclosing this line in parenthesis, like so: 事实证明,通过在括号中包含这一行可以很容易地纠正它,如下所示:

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

Note: The GetAttribute extension method comes from here . 注意: GetAttribute扩展方法来自此处

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM