1
votes

I have written the following Code to implement sorting. I want to maintain the sortingData(OrderDirection,SortField) between two requests for Sorting. Somehow I'm not able to achieve that.

//In .cshtml Page

    @{
        SortingPagingInfo info = (SortingPagingInfo)ViewData["SortingPagingInfo"];
    }
<form method="post">
    @Html.Hidden("SortField", info.SortField)
    @Html.Hidden("SortDirection", info.SortDirection)
    @Html.Hidden("PageCount", info.PageCount)
    @Html.Hidden("PageSize", info.PageSize)
    @Html.Hidden("CurrentPageIndex", info.CurrentPageIndex)
 <table class="table">
        <thead>
            <tr>
                <th>
                    <a asp-page="./Page" asp-route-sortData="@info">
                        @Html.DisplayNameFor(model => model.Tabl[0].Col1)
                    </a>

                </th>
                <th>
                    <a asp-page="./Page" asp-route-sortData="@info">
                        @Html.DisplayNameFor(model => model.Tabl[0].Col2)
                    </a>

                </th>
 <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model.Table)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Col1)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Col2)
                    </td>
</tr>
            }
        </tbody>
    </table>

</form>

-----In cshtml.cs Page

The get Request is as below:

public async Task OnGetAsync(SortingPagingInfo sortData)
        {
            SortingPagingInfo info = new SortingPagingInfo();
            if (string.IsNullOrEmpty(sortData.SortDirection))
            {
                info.SortField = "Col1";
                info.SortDirection = "OrderBy";
                info.PageSize = 10;
                info.PageCount = Convert.ToInt32(Math.Ceiling((double)(_context.Tab.Count()
                               / info.PageSize)));
                info.CurrentPageIndex = 0;
                this.sortPageData = info;
                ViewData["SortingPagingInfo"] = info;
            }
            else
            {
                info = (SortingPagingInfo)ViewData["SortingPagingInfo"];
            }
            tab1= await _context.Tabl.OrderByDynamic(info.SortField, info.SortDirection).ToListAsync();


        }

I'm trying to pass the object and maintain it in ViewData so that It could be accessed. But everytime, only null value is returned. Is there any better way for implementing Sorting with Razor Pages or If this could be made to work?

1
What do those URLs in the <th> tags look like? - bommelding

1 Answers

1
votes

You cannot simply dump an object as a route data param on a link. What will actually happen here is that Razor will simply call ToString on your info instance. You have a few options:

  1. Break out each property and pass it individually:

    <a asp-page="./Page" asp-route-sortField="@info.SortField" asp-route=sortDirection="@info.SortDirection" asp-route-pageCount="@info.PageCount" asp-route-pageSize="@info.PageSize" asp-route-currentPageIndex="@info.CurrentPageIndex">
    
  2. Serialize the object and then deserialize it in your action:

    <a asp-page="./Page" asp-route-sortData="@JsonConvert.SerializeObject(info)">
    

    Then, your action would need to be changed to accept a string:

    public async Task OnGetAsync(string sortData)
    

    And inside the action, you'd then deserialize that string back into an instance of SortingPagingInfo:

    var info = JsonCovert.DeserializeObject<SortingPagingInfo>(sortData);
    
  3. Make your links submit buttons instead (you can still style them as links) and have them actually submit a form with all this data:

    <form asp-page-handler="./Page" method="get">
        @Html.Hidden("SortField", info.SortField)
        @Html.Hidden("SortDirection", info.SortDirection)
        @Html.Hidden("PageCount", info.PageCount)
        @Html.Hidden("PageSize", info.PageSize)
        @Html.Hidden("CurrentPageIndex", info.CurrentPageIndex)
        <button type="submit" class="btn btn-link">
            @Html.DisplayNameFor(model => model.Tabl[0].Col1)
        </button>
    </form>
    

    However, you currently have a form that wraps your entire table, and you cannot have forms within forms. As a result, you would need to restructure your HTML to ensure that each of these links was outside of any other forms on the page.