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

南笙酒味 提交于 2019-12-10 13:52:45

问题


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.

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.


回答1:


This is not a limitation of the WebGrid or Razor. It's a limitation of the C# dynamic type. 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.

I wrote about this exact issue a couple of years ago.




回答2:


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:

@using MvcApplication1.Controllers

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

The page prints out:

Hello

However, this version of the 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?)

So I suspect Jon was correct and this is a limitation with Razor. (why it works with HtmlHelper leaves me a bit mystified though)




回答3:


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.



来源:https://stackoverflow.com/questions/15580257/why-cant-i-use-my-extension-method-in-a-delegate-in-the-razor-webgrid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!