Home > Mobile >  ASP.NET Core MVC Reusable HTML Components
ASP.NET Core MVC Reusable HTML Components

Time:06-29

I am starting to dive in deeper to ASP.NET Core and probably my #1 feature with Blazor is the ability to reuse components with RenderFragment parameters, such as:

<div  id="@this.ClientId">
    <!--trigger button-->
    <div >
        <button  aria-label="@this.AriaLabel" aria-haspopup="true" aria-expanded="false" aria-controls="@($"{this.ClientId}_dropdown")">
            <i ></i>
        </button>
    </div>
    <!--dropdown-->
    <div  id="@($"{this.ClientId}_dropdown")" aria-hidden="true" role="menu">
        <div >
            @ChildContent
        </div>
    </div>
</div>

The C# for this component is basic as well (main property is a RenderFragment called ChildContent that gets rendered inside the view via @ChildContent.

Is there an equivalent for this with ASP.NET Core MVC apps that don't use Blazor? I've spent a few hours researching ViewComponents, but I can't seem to figure out how my view can access a RenderFragment on a ViewComponent.

For instance, a small ViewComponent I am trying to setup has the following markup:

<div >
    <div >
        <h3 >@this.Title</h3>
        <div >
            <button type="button" >
                Action
            </button>
        </div>
    </div>
    <div >
        @ContentTemplate
    </div>
    <div >
        Footer
    </div>
</div>

My ViewComponent is quite basic as well, as the intention here isn't to have it retrieving data - it's meant to be a basic card template (Bootstrap 5), so if Bootstrap 6 changes the structure of a card (like they did with 4 ==> 5, where it's no longer a "portlet"), I fix it in one spot and the hundreds of views I have will automatically get the new structure, vs. changing it everywhere. Here's the ViewComponent:

[ViewComponent(Name = "Card")]
    public class CardViewComponent : ViewComponent
    {
        /// <summary>
        /// Gets or sets the card's body
        /// </summary>
        [Parameter]
        public RenderFragment ContentTemplate { get; set; }

        /// <summary>
        /// Gets or sets card's title
        /// </summary>
        [Parameter]
        public string Title { get; set; }

        /// <summary>
        /// Invokes this component to render the associated content.
        /// </summary>
        /// <returns>An IViewComponentResult.</returns>
        public IViewComponentResult Invoke()
        {
            return View("Default");
        }
    }

I feel like I'm right on the cusp of figuring this out, but just can't quite get there. I've also reviewed the use of a @helper which is pretty close, but the syntax for a Razor/Blazor app is much cleaner and will let my designer team (who know nothing about .Net) better understand what's happening, e.g.:

<Card Title="Section Title">
     <p>I'm the body and would render inside the `ChildContent` RenderFragment!</p>
</Card>

Any suggestions would be much appreciated!

CodePudding user response:

From your question, You just want to have a Reusable HTML to be a basic card template instead of retrieving data, SO I suggest you to use Partial View.

The difference between Partial View and ViewComponent described in Microsoft Document as:

Don't use a partial view where complex rendering logic or code execution is required to render the markup. Instead of a partial view, use a view component.

You can follow the link I shared before to learn more about Partial View in Asp.Net core.

CodePudding user response:

A lucky Google search helped me track down this article regarding tag helpers. Utilizing that, I don't need a RenderFragment (which seems to be Blazor-specific) - I can add inner HTML as needed, by appending HTML to the TagHelperOutput parameter contained inside the Process and ProcessAsync methods. It's not quite as simple as what RenderFragment brings to the table, but it solves my use case.

  • Related