Issue with loading partial view via ajax call on tabbed razor page

Michael Mastro II 51 Reputation points
2023-05-07T21:07:41.89+00:00

Good day, I am having an issue with a razor page not loading my partial view. I believe the issue is in the jquery script. I have a Razor Page with 2 tabs. The first tab loads fine, when I select the second tab it moves to that tab, but the handler never gets called.

In the Razor Page c# code I have an OnGetAsync() and a OnGetAsyncApplicationsPartial(). The OnGetAsyncApplicationsPartial never gets hit, as I have a break point right at the beginning and it never reaches there.

Razor Page I have the following:


@page "{handler?}"
@model AllPermissionsModel
@{
}
@section scripts{
    <script>
        var applicationsLoaded = false;
        $(function(){
            $('a[data-bs-toggle="tab"]').on('.shown.bs.tab', function(e) {
                switch($(e.target).attr('aria-controls')) {
                    case "applications":
                    if(!applicationsLoaded) {
                        $('#applications').load(`/tabs/applications?handler=ApplicationsPartial`)
                        applicationsLoaded = true;
                    }
                    break;
                }
            });
        });
    </script>
}

<ul class="nav nav-tabs" id="permTab" role="tablist">
    <li class="nav-item" role="tab">
        <a class="nav-link active" id="general-tab" data-bs-toggle="tab" href="#general" aria-controls="general">General Permissions</a>
    </li>
    <li class="nav-item" role="tab">
        <a class="nav-link" id="applications-tab" data-bs-toggle="tab" href="#applications" aria-controls="applications">Application Permissions</a>
    </li>
</ul>
<div class="tab-content" id="permTabContent">
    <div class="tab-pane fade show active" id="general" role="tabpanel" aria-labelledby="general-tab">
        <table class="table table-responsive table-hover">
            <thead class="table table-info">
                <tr>
                    <th>Unique Name</th>
                    <th>Node One</th>
                    <th>Node Two</th>
                    <th>Node Three</th>
                    <th>Permission Name</th>
                    <th>Description</th>
                    <th>NodeType</th>
                    <th>Client</th>
                    <th>Api</th>
                    <th>Other Requirements</th>
                </tr>
            </thead>
            <tbody>
                @foreach(var item in @Model.PermissionsModels)
                {
                    <tr>
                        <td>@item.UniqueName</td>
                        <td>@item.NodeOne</td>
                        <td>@item.NodeTwo</td>
                        <td>@item.NodeThree</td>
                        <td>@item.SettingName</td>
                        <td>@item.Description</td>
                        <td>@item.NodeType</td>
                        <td>@item.Client</td>
                        <td>@item.Api</td>
                        <td>@item.OtherRequirements</td>
                    </tr>
                }
            </tbody>
        </table>        
    </div>
    <div class="tab-pane fade" id="applications" role="tabpanel" aria-labelledby="applications-tab"></div>
</div>

On the partial I have the following:


@model IList<AllPermissionsModel.PermissionsModel>
@{
}
<table>
    <thead>
        <tr>
            <th>Unique Name</th>
            <th>Node One</th>
            <th>Node Two</th>
            <th>Node Three</th>
            <th>Permission Name</th>
            <th>Description</th>
            <th>NodeType</th>
            <th>Client</th>
            <th>Api</th>
            <th>Other Requirements</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>@item.UniqueName</td>
                <td>@item.NodeOne</td>
                <td>@item.NodeTwo</td>
                <td>@item.NodeThree</td>
                <td>@item.SettingName</td>
                <td>@item.Description</td>
                <td>@item.NodeType</td>
                <td>@item.Client</td>
                <td>@item.Api</td>
                <td>@item.OtherRequirements</td>
            </tr>
        }
    </tbody>
</table>

I know the toggle portion of the jQuery works as the Applications Tab takes over when selected, it just never calls the ?handler=ApplicationsPartial, that I can tell. But I do not believe it does since the partial breakpoint never gets hit. Any thoughts of where I went wrong?

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,532 questions
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,291 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,496 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Chen Li - MSFT 1,221 Reputation points
    2023-05-08T02:33:09.4633333+00:00

    Hi @Michael Mastro II,

    There is something wrong with your jQuery method, what is .shown.bs.tab? Maybe you want click events:

    $('a[data-bs-toggle="tab"]').on('click', function(e) {
        //...
    });
    

    Below is a working demo, you can refer to it:

    Index.cshtml.cs:

    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;
    
        public List<PermissionsModels> PermissionsModels { get; set; }
    
        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        }
    
        public IActionResult OnGet()
        {
            PermissionsModels = new List<PermissionsModels>()
            {
                new PermissionsModels()
                {
                    UniqueName = "Name1",
                    NodeOne = "One1",
                    NodeTwo = "Two1",
                    NodeThree = "Three1"
                },
                new PermissionsModels()
                {
                    UniqueName = "Name2",
                    NodeOne = "One2",
                    NodeTwo = "Two2",
                    NodeThree = "Three2"
                },
                new PermissionsModels()
                {
                    UniqueName = "Name3",
                    NodeOne = "One3",
                    NodeTwo = "Two3",
                    NodeThree = "Three3"
                }
            };
            return Page();
        }
    }
    

    Index.cshtml:

    @section scripts{
        <script>
            var applicationsLoaded = false;
            $(function(){
                $('a[data-bs-toggle="tab"]').on('click', function(e) {
                    switch($(e.target).attr('aria-controls')) {
                        case "applications":
                        if(!applicationsLoaded) {
                                $('#applications').load(`/tabs/applications?handler=ApplicationsPartial`)
                            applicationsLoaded = true;
                        }
                        break;
                    }
                });
            });
        </script>
    }
    
    <ul class="nav nav-tabs" id="permTab" role="tablist">
        <li class="nav-item" role="tab">
            <a class="nav-link active" id="general-tab" data-bs-toggle="tab" href="#general" aria-controls="general">General Permissions</a>
        </li>
        <li class="nav-item" role="tab">
            <a class="nav-link" id="applications-tab" data-bs-toggle="tab" href="#applications" aria-controls="applications">Application Permissions</a>
        </li>
    </ul>
    <div class="tab-content" id="permTabContent">
        <div class="tab-pane fade show active" id="general" role="tabpanel" aria-labelledby="general-tab">
            <table class="table table-responsive table-hover">
                <thead class="table table-info">
                    <tr>
                        <th>Unique Name</th>
                        <th>Node One</th>
                        <th>Node Two</th>
                        <th>Node Three</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var item in @Model.PermissionsModels)
                    {
                        <tr>
                            <td>@item.UniqueName</td>
                            <td>@item.NodeOne</td>
                            <td>@item.NodeTwo</td>
                            <td>@item.NodeThree</td>
                        </tr>
                    }
                </tbody>
            </table>
        </div>
        <div class="tab-pane fade" id="applications" role="tabpanel" aria-labelledby="applications-tab"></div>
    </div>
    
    

    Applications.cshtml.cs:

    public class ApplicationsModel : PageModel
    {
        public List<PermissionsModels> permissions { get; set; }
        public IActionResult OnGetApplicationsPartial()
        {
            permissions = new List<PermissionsModels>()
            {
                new PermissionsModels()
                {
                    UniqueName = "Name4",
                    NodeOne = "One4",
                    NodeTwo = "Two4",
                    NodeThree = "Three4"
                },
                new PermissionsModels()
                {
                    UniqueName = "Name5",
                    NodeOne = "One5",
                    NodeTwo = "Two5",
                    NodeThree = "Three5"
                },
                new PermissionsModels()
                {
                    UniqueName = "Name6",
                    NodeOne = "One6",
                    NodeTwo = "Two6",
                    NodeThree = "Three6"
                }
            };
            return Page();
        }
    }
    

    Applications.cshtml:

    @page "/tabs/applications"
    @{
        Layout = null;
    }
    @model ApplicationsModel
    @await Html.PartialAsync("../Shared/_PartialPage", Model.permissions)
    

    Please note that you need to set your own Layout or null, otherwise the header and footer will also be loaded by using the load method.

    _PartialPage.cshtml:

    @model IList<PermissionsModels>
    <table>
        <thead>
            <tr>
                <th>Unique Name</th>
                <th>Node One</th>
                <th>Node Two</th>
                <th>Node Three</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            {
                <tr>
                    <td>@item.UniqueName</td>
                    <td>@item.NodeOne</td>
                    <td>@item.NodeTwo</td>
                    <td>@item.NodeThree</td>
                </tr>
            }
        </tbody>
    </table>
    

    Test Result:

    User's image

    Of course, you can also directly use return Partial("_PartialName", model); For more details, you can refer to this document.


    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Best Regards,

    Chen Li


    Update:

    Hi @Michael Mastro II,

    There is something wrong with your method name, so you will not call the corresponding method. Please change public async Task<PartialViewResult> OnGetAsyncApplicationsPartial() to public async Task<PartialViewResult> OnGetApplicationsPartialAsync().

    Also, you're using the wrong model in your partial view. You are passing IList<AllPermissionsModel.PermissionsModel>, but using ApplicationPermissionsModel, which causes a dictionary mismatch. Please change @model ApplicationPermissionsModel to @model

    IList<AllPermissionsModel.PermissionsModel>, and change @foreach (var item in Model.PermissionsModels) to @foreach (var item in Model).

    Then your code should work.


  2. AgaveJoe 26,676 Reputation points
    2023-05-11T10:34:01.5833333+00:00

    The route is configured to include the handler in the route; @page "{handler?}". Either remove {handler?} or update the jQuery URL; /path/ApplicationsPartial.

    0 comments No comments