How to define function that returns html in asp.ne

2020-08-24 17:29发布

问题:

Basically I need something like old asp.net

@helper MakeNote(string content) {
    <p><strong>Note</strong>&nbsp;&nbsp; @content    </p>
}

or JSX

MakeNote(note) {
   return (<div>Note {note}</div>);
}

A partial view is not an option. I am happy with either a function returning an IHtmlString, or a function writing to the underlying writer.

It also needs to support Razor Syntax (not just string concatenation) inside the function.

回答1:

Since ASP.NET Core 3.0, we can declare Local Functions containing markup to serve as templating methods, inside Razor Code Blocks:

@{
    void RenderName(string name)
    {
        <p>Name: <strong>@name</strong></p>
    }

    RenderName("Mahatma Gandhi");
    RenderName("Martin Luther King, Jr.");
}

Which renders the following HTML Code:

<p>Name: <strong>Mahatma Gandhi</strong></p>
<p>Name: <strong>Martin Luther King, Jr.</strong></p>

Documentation: https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-3.0#razor-code-blocks


(just for sake of completion) In ASP.NET Core 2.0 we can use Templated Razor delegates, which combined with the <text></text> razor tag (Explicit Delimited Transition), allow us to make something similar to an old day's ASP.NET MVC @helper tag:

@{
    Func<string, object> RenderName = @<text>
        <p>
            Name: <strong>@item</strong>
        </p>;
    </text>;
}

<div>
    @RenderName("Victor")
</div>

Which renders the following HTML Code:

<div>
    <p>
        Name: <strong>Victor</strong>
    </p>
</div>

Documentation: https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-2.0#templated-razor-delegates
Documentation <text></text>: https://docs.microsoft.com/en-us/aspnet/core/mvc/views/razor?view=aspnetcore-2.0#razor-code-blocks



回答2:

You might be looking for @functions that use Html.Raw.

Here is an example that shows two function styles. The first uses a traditional block body, the second uses an expression-body.

Both of them have the $@ prefix on the string.

  • The $ enables {interpoloation} in the string.
  • The @ makes a verbatim string, which can span multiple lines.

The third way is somewhat of a hack that lets us parse Razor inside the function. It's as close as we seem to be able to get to the original @helper syntax.

SomeRazorFile.cshtml

@using Microsoft.AspNetCore.Html

@functions 
{
    IHtmlContent MakeNote(string content) 
    {
        return Html.Raw($@"
            <p>
                <strong>Note</strong> {content}
            </p>
        ");
    }

    // an alternative that uses method shorthand
    IHtmlContent MakeNoteToo(string content) => Html.Raw($@"
        <p>
            <strong>Note</strong> {content}
        </p>
    ");
}

@{
    // an alternative that parses razor
    Func<string, IHtmlContent> MakeNoteThree = 
        @<p>
            <strong>Note</strong> {@item}
        </p>;
}

<div>
    @MakeNote("Foo")
    @MakeNoteToo("Bar")
    @MakeNoteThree("Baz")
</div>

Edit: Added an example that parses Razor. See https://github.com/aspnet/Razor/issues/715 for details.