如何將 lambda 傳遞給 Razor 輔助方法? (How to pass in a lambda to a Razor helper method?)


問題描述

如何將 lambda 傳遞給 Razor 輔助方法? (How to pass in a lambda to a Razor helper method?)

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);
    }
}

(by enceeMoeriteamchong)

參考文件

  1. How to pass in a lambda to a Razor helper method? (CC BY‑SA 3.0/4.0)

#lambda #razor #html-helper #asp.net-mvc #C#






相關問題

Lambda 表達式中的 SQL WHERE 等價物是什麼? (What's the equivalence of an SQL WHERE in Lambda expressions?)

如何將 lambda 傳遞給 Razor 輔助方法? (How to pass in a lambda to a Razor helper method?)

lỗi biểu thức lambda: biểu thức phải là giá trị có thể sửa đổi (lambda expression error: expression must be a modifiable lvalue)

如何在 PySpark 中有效地按值排序? (How to sort by value efficiently in PySpark?)

將列表列表減少為字典,以子列表大小為鍵,出現次數為值 (Reduce list of list to dictionary with sublist size as keys and number of occurances as value)

匿名類作為泛型參數 (anonymous class as generic parameter)

如何為 lambda 中的運算符賦予不定性? (How to give infixities to operators in lambda?)

如何發出委託或 lambda 表達式 (Howto emit a delegate or lambda expression)

深入學習 C# 表達式樹的最佳資源是什麼? (What is the best resource for learning C# expression trees in depth?)

根據最高日期從 IGrouping 中獲取項目 (Get an item from a IGrouping based on the highest date)

如何在 C# 中使用“param”來獲取這個示例? (How can I get this example using "param" in C# to work?)

如何使用 C# 中的 Lambda 表達式僅返回沒有來自另一個表的行的行 (How to return only rows where no rows from another table using Lambda Expressions in C#)







留言討論