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