Search code examples
c#.netasp.net-corerazor

Razor, not MVC: How to call page model Method to Update Database on button click


I've been trying to get my way of thinking away from Web Forms and into .NET5/Core Razor. I keep hearing MVC is being over-shadowed by Razor pages, but all of the help I find is MVC related. I'm using Razor, and Dapper so I can avoid the Entity Framework. I'm getting my song list (from a SQL db) displayed in an HTML table, and I have buttons on each row I want to use to click to move the row up or down. This requires an update to the sort_order column in my song table. I have no problems with the logic of updating the table, but how do I call my method in my cs page and pass the parameters?

sortSongs(int currentPlace, string sortDirection) in my cs page.

<table id="DT_load2" class="table table-striped table-bordered" style="width:100%">
    <thead style="align-content:center;">
        <tr>
            <th>Title</th>
            <th>Artist</th>
            <th>Key</th>
            <th>Tempo</th>
            <th>Genre</th>
            <th>Feel</th>
            <th>Lyrics</th>
            <th>Sort</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.getSongs())
        {
            
            if (cnt == 0) {<tr><td colspan="8" style="background-color: darkgray;font-weight: 600;color: white;">Group @grpcnt</td></tr>}
            cnt++;
            if (cnt == 3) { grpcnt++; }
            if (cnt == 4) { cnt = 1; }

    <tr>
        <td>
            <a href="@Html.DisplayFor(modelItem => item.link)" target="new">@Html.DisplayFor(modelItem => item.title)</a>
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.artist)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.song_key)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.tempo)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.genre)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.feel)
        </td>
        <td>
            Lyrics
        </td>
        <td>
            <button type="button" class="btn btn-secondary" [email protected](Convert.ToInt32(@Html.DisplayFor(modelItem => item.id)),"U")>
                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-up" viewBox="0 0 16 16">
                    <path fill-rule="evenodd" d="M8 15a.5.5 0 0 0 .5-.5V2.707l3.146 3.147a.5.5 0 0 0 .708-.708l-4-4a.5.5 0 0 0-.708 0l-4 4a.5.5 0 1 0 .708.708L7.5 2.707V14.5a.5.5 0 0 0 .5.5z" />
                </svg>
                <span class="visually-hidden"></span>
            </button>
            <button type="button" class="btn btn-secondary">
                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-arrow-down" viewBox="0 0 16 16">
                    <path fill-rule="evenodd" d="M8 1a.5.5 0 0 1 .5.5v11.793l3.146-3.147a.5.5 0 0 1 .708.708l-4 4a.5.5 0 0 1-.708 0l-4-4a.5.5 0 0 1 .708-.708L7.5 13.293V1.5A.5.5 0 0 1 8 1z" />
                </svg>
                <span class="visually-hidden"></span>
            </button>
        </td>
    </tr>

            if (cnt == 3)
            {
                <tr><td colspan="8" style="background-color:darkgray;font-weight:600;color:white;">Group @grpcnt</td></tr>
            }
        }
    </tbody>
</table>

Solution

  • @Model.sortSongs(Convert.ToInt32(@Html.DisplayFor(modelItem => item.id)),"U")

    You are not sending request to the method. Route in Razor pages is different from that in MVC. The handler should be start with OnGet or OnPost, to represent it a get or post method. Here you can use anchor instead of button, like below:

    Index.cshtml:

    <a href="Index?handler=sortSongs&currentPlace=1&sortDirection=U" type="button" class="btn btn-secondary">click</a>
    

    Index.cs.cshtml:

    public void OnGetSortSongs(int currentPlace, string sortDirection)
    {
            
    }
    

    Result:

    enter image description here