Search code examples
visual-studioasp.net-corerazormenu

Dynamic menu in Layout page (Razor pages)


I have a problem and couldn't find a solution.

I am developing a site in Visual Studio 2022, ASP.NET Core 6.0 Razor pages. (not MVC)

I made a database drived (MSSQL) dynamic menu for the navigation. I made this menu in a temp page and it works without any problem. Problem starts, when i want to include this menu in the navbar at the Layout page.

"partial page" doesn't seems like a solution to me, any suggestion or samples how i could make this ?


Solution

  • Edit: I updated this be more relevent to razor pages cause I didnt see you where using controllers intially. However, I left in a lot of my controller stuff because I am lazy.

    It depends on how you want to structure your nav view two ways RenderSection or ViewComponent.

    Render Section:

    https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.razor.razorpage.rendersection?view=aspnetcore-7.0

    you will have a place in your layout where you say @RenderSection("Navigation",true)

    then in your views (the main cshtml you are returning) you will have a

    @section Navigation
    {
        <div>Nav section </div>
    }
    

    View Component https://www.learnrazorpages.com/razor-pages/view-components

    In your layout you will have @await Component.InvokeAsync(typeof(NavViewComponent))

    You will have a class called NavViewComponent (You can use dependency injection in the class constructor)

    That will have a method name

    public async Task<IViewComponentResult> InvokeAsync() {
      todo logic
      return View()
    }
    

    And a view located in shared/views/Nav

    The view in the folder should be called Default

    You can also set up different views in the folder and call them in your NavViewComponent by returning View("{ViewName}") Then in add that {ViewName} in the same place as the default view.

    The two differences between these two methods is how much the Main body view and the nav need to communicate. For example, if my Nav screen is role, user, or controller based and does not have anything to do with the main body. In this case use the view component because otherwise you would have to RenderSection(nav) in every single one of the views. However, if something in http parameters directly controls what's in the Nav or something in the main view controls it use the render section.

    Keep in mind that this is just a recommendation of why you might go with one over the other. If in the future, you needed to use something in http response in a viewcomponent you could just inject the httpcontext into the view component and use it there. However, this would be a little messier.

    ========Edit============ The reason this is happening is you dont pass AltKat into your view Model.

    Assuming you are using entity framework

    Adding a list property to your AnaKategori Model

    public List<AltKategori> AltCategories {get;set;}
    

    Then in the View Component

    InvokeAsync() {
    var AnaKat = await dbcontext.AnaKategori.Include(m => m.AltCategories).ToListAsync();
    return View(anaKat);
    }
    

    Then in the view

    @foreach(var menu in Model) {
      <li> @menu.AnaKatAdi</li>
      @foreach(var menu2 in menu.AltCategories) {
     <blockquote>@menu2.AnaKatAdi</backquote>
    }
    }