问题
I have a razor helper method that needs to take in a Func<>
that will return some HTML content to print out. This is what I originally had:
@helper node(string title, Func<HelperResult> descriptions)
{
....
<div>@descriptions()</div>
....
}
@node("title",
new Func<HelperResult>(() =>
{
return new HelperResult(
@<text>
<span>"desc1"</span>
<span>"desc2"</span>
</text>);
}))
Unfortunately with this my text never gets printed out. No error either.
So I learned about inline helpers, and changed the calling method to this:
@node("title",
@<text>
<span>"desc1"</span>
<span>"desc2"</span>
</text>)
However now I get a compilation error saying
"Delegate 'System.Func' does not take 1 arguments".
But I'm not passing in any arguments.
So if I change it to Func<object,HelperResult>
and then call it using @descriptions(null)
I get the following error:
"Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type"
I'm sure I have something wrong somewhere, but I'm not sure what it is.
Edit: I think I may have solved that problem but it introduces some other issues.
What I did was to cast the lambda before passing into a dynamic method. I guess that's what the error was trying to say:
@node("title",
((Func<dynamic, HelperResult>)(@<text>
<span>"desc1"</span>
<span>"desc2"</span>
</text>))
That works and it prints out the span
tags correctly. Unfortunately I have to pass in a useless parameter when calling this Func
.
Now the issue I have is that my real function does a bit more than just write some spans. It's more like this:
@node("title",
((Func<dynamic, HelperResult>)(@<text>
<span>@Helpers.Format(resource.Description,"item")</span>
</text>))
Where @Helpers.Format
is another helper and resource is a (dynamic) variable from the page model.
Of course now the code runs but nothing is printed out (inside the <span>
tag). I put a breakpoint inside my Format
helper function, and it hits it and all the parameters are correctly set, so I'm not sure why it wouldn't output correctly. Similarly if I just change it to
resource.Description
then nothing still gets output.
Since it works well outside of this context, I wonder does Razor's inline helpers not capture the outer variables?
回答1:
Actually HelperResult is something Microsoft would rather you didn't use, as evidenced by documentation:
public class HelperResult : IHtmlString in namespace System.Web.WebPages
Summary: This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.
A possible solution to your problem might be to wrap your description function in another helper and then pass that helper as a method group to your node helper, like this:
@helper Node(string title, Func<HelperResult> descriptions)
{
<div>@descriptions()</div>
}
@helper Description() {
<span>desc1</span>
<span>desc2</span>
}
@Node("title", Description)
In any case, your first idea shouldn't work because a parameter of type Func is in fact equal to a parameterless function, in which case you need to write the lambda expression like this:
myFunction( () => doSomething)
So your function call would have been:
@node("title", () =>
@<text>
<span>"desc1"</span>
<span>"desc2"</span>
</text>)
Since the future of these helpers is a bit dubious though, I would consider switching to either HtmlHelpers for small snippets of html or Partials for larger chunks.
回答2:
@Test(new Func<object, HelperResult>[]{@<text>hello</text>})
@Test(new Func<object, HelperResult>[]{@<text>hello</text>,@<text>world</text>})
@helper Test(params Func<object, HelperResult>[] results)
{
foreach (var result in results)
{
@result(null);
}
}
来源:https://stackoverflow.com/questions/14328303/how-to-pass-in-a-lambda-to-a-razor-helper-method