Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditionally call ViewComponent inside Razor Page

I'm new to Razor Pages and View Components and I'm cleary failing to put my head around the concepts:

I have a Example page, this page is rendered inside a _Layout, like the following:

@page "{value1?}/{value2?}"
@model MyProject.Pages.ExampleModel
@{
    ViewData["Title"] = "Example";
}

Now I need to call a ViewComponent conditionally based on value1 and value2:

public class ExampleModel : PageModel
{
    public async Task<IActionResult> OnGetAsync(string value1, string value2)
    {
        // this contains a lot of logic, db access etc, and passing objects to the component, but I'm abbreviating

        if (value1 == null && value2 == null)
        {
            return this.ViewComponent(nameof(SomeComponent));
        }
        else
        {
            return this.ViewComponent(nameof(SomeOtherComponent));
        }

        // return Page();
    }
}

This is the extension I'm using to call the components:

public static class PageModelExtensions
{
    public static ViewComponentResult ViewComponent(this PageModel pageModel, string componentName, object arguments)
    {
        return new ViewComponentResult
        {
            ViewComponentName = componentName,
            Arguments = arguments,
            ViewData = pageModel.ViewData,
            TempData = pageModel.TempData
        };
    }
}

This is working, but because I'm not calling return Page(), the component is being rendered without calling _Layout. How should I approach this?

like image 338
lolol Avatar asked Oct 13 '25 04:10

lolol


1 Answers

If you want to render a View Component from within a Razor Page like this, one option is to specify the name of said View Component in your PageModel class and then use Component.InvokeAsync in the correpsonding .cshtml file. Here's what that might look like:

Example.cshtml.cs

public class ExampleModel : PageModel
{
    public string ViewComponentName { get; set; }

    public async Task<IActionResult> OnGetAsync(string value1, string value2)
    {
        ...

        if (value1 == null && value2 == null)
            ViewComponentName = nameof(SomeComponent);
        else
            ViewComponentName = nameof(SomeOtherComponent);

        return Page();
    }
}

Example.cshtml

@page "{value1?}/{value2?}"
@model MyProject.Pages.ExampleModel

...

@await Component.InvokeAsync(Model.ViewComponentName)

In Example.cshtml.cs, ViewComponentName is a new property that (unsurprisingly) represents the name of the View Component that should be rendered as part of the page, which is realised in Example.cshtml using Component.InvokeAsync.

like image 137
Kirk Larkin Avatar answered Oct 14 '25 20:10

Kirk Larkin