Question:
How to Fix Include on Razor View Not Working issue?

Problem:

I've done basic sorts before and not had an issue, but this one has me stumped as to what I am doing wrong. All it returns is a blank page.


Details.cs (showing the sort code)


using RabiesClinics.Data;

using RabiesClinics.Model;

using Microsoft.AspNetCore.Mvc;

using Microsoft.AspNetCore.Mvc.RazorPages;

using Microsoft.EntityFrameworkCore;


namespace RabiesClinics.Pages.Pets;


[BindProperties]


public class DetailsModel : PageModel

{

    private readonly ApplicationDbContext _db;


    public Pet Pet { get; set; }

    public Vaccine Vaccine { get; set; }

    public IEnumerable<Vaccine> VaxList { get; set; }


    public string VaxDateSort { get; set; }


    public DetailsModel(ApplicationDbContext db)

    {

        _db = db;

    }


    public async Task<IActionResult> OnGetAsync(int ownerid, string id, string sortOrder)

    {

        var ownerid1 = ownerid;


        Pet = _db.Pet.Include(pet => pet.Vaccines).FirstOrDefault(pet => pet.PetId == id);


        VaxDateSort = sortOrder == "VaxDate_Asc_Sort" ? "VaxDate_Desc_Sort" : "VaxDate_Asc_Sort";


        IQueryable<Model.Vaccine> vaccine = from s in _db.Vaccine select s;


        switch (sortOrder)

        {

            case "VaxDate_Asc_Sort":

                vaccine = vaccine.OrderBy(s => s.DateVaccinated.ToString());

                break;

            case "VaxDate_Desc_Sort":

                vaccine = vaccine.OrderByDescending(s => s.DateVaccinated.ToString());

                break;

            default:

                vaccine = vaccine.OrderBy(s => s.DateVaccinated.ToString());

                break;

        }

        Vaccine = await vaccine.ToListAsync();


        if (Pet is null)

            return new NotFoundResult();

        else

            return Page();

    }


}


Pet Details view where the sort occurs (shortened for space):

@page

@using RabiesClinics.Model

@model RabiesClinics.Pages.Pets.DetailsModel


<form method="post">

    <div class="border p-3 mt-4">

        <div class="row pb-2">

            <h2 class="text-primary pl-3">Pet Details <img src="~/Images/PawPrints.png" /></h2>

            <hr />

        </div>

        <table class="table table-borderless" style="width:100%">

            <tr>

                <td style="width: 20%">

                    <div class="mb-3">

                        <label asp-for="Pet.OwnerId"></label>

                        <input asp-for="Pet.OwnerId" name="ownerid" disabled class="form-control" />

                    </div>

                </td>

                <td style="width: 20%">

                    <div class="mb-3">

                        <label asp-for="Pet.PetId"></label>

                        <input asp-for="Pet.PetId" name="id" disabled class="form-control" />

                    </div>

                </td>

                <td style="width: 20%">

                    <div class="mb-3">

                        <label asp-for="Pet.PetName"></label>

                        <input asp-for="Pet.PetName" type="text" disabled class="form-control"/>

                    </div>

                </td>

                <td style="width: 20%">

                    <div class="mb-3">

                        <label asp-for="Pet.LastVaxDate"></label>

                        <input asp-for="Pet.LastVaxDate" type="text" disabled class="form-control" />

                    </div>

                </td>

                <td style="width: 20%">

                    <div class="form-group, mb-3">

                        <label asp-for="Pet.Status"></label>

                        <br />

                        @foreach (var item1 in Html.GetEnumSelectList<Status>())

                        {

                            <input type="radio" disabled asp-for="Pet.Status" value="@item1.Text" />

                        @item1.Text

                        }

                    </div>

                </td>

            </tr>

        </table>

        <hr />

        <h4>Vaccines</h4>

        <br />

        <table class="table table-bordered table-striped width:100%">

            <thead>

                <tr>

                    <th>

                        Tag No

                    </th>

                    <th>

                        <a asp-page="./Details" asp-route-sortOrder="@Model.VaxDateSort">Date Vaxxed</a>

                    </th>

                    <th>

                        Print Rabies Certificate

                    </th>

                </tr>

            </thead>

            <tbody>

                @for (var i = 0; i < Model.Pet.Vaccines.Count; i++)

                {

                    <tr>

                        <td style="width: 10%">

                            <div class="mb-3">

                                <input asp-for="Pet.Vaccines[i].RabiesTagNo" type="text" readonly class="form-control-plaintext" />

                            </div>

                        </td>

                        <td style="width: 10%">

                            <div class="mb-3">

                                <input asp-for="Pet.Vaccines[i].DateVaccinated"  type="date" readonly class="form-control-plaintext" />

                            </div>

                        </td>

                        <td width="10%">

                            <div class="w-75 btn-group" role="group">

                                <!--Line below is good.-->

                                <a asp-page="/RabiesCertificates/Details" class="btn btn-primary mx-2" asp-route-id="@Model.Pet.PetId" asp-route-vaxdate="@Model.Pet.Vaccines[i].DateVaccinated">

                                    <i class="bi bi-printer"></i>

                                </a>

                            </div>

                        </td>

                    </tr>

                }

        </table>

        <div>

            <a asp-page="/Owners/Details" asp-route-ownerid="ownerid1" asp-route-id="@Model.Pet.OwnerId"  class="btn btn-primary" style="width: 250px;">Back to Owner Details</a>

        </div>

    </div>

</form>


@section Scripts{

    <partial name="_ValidationScriptsPartial"/>

}


If someone could point out where I have gone astray, I would much appreciate it! I have learned a lot from this forum so far that I have been able to apply on multiple apps!


ADDED: Update based on suggestion


public async Task<IActionResult> OnGetAsync(int ownerid, string id, string sortOrder, DateTime vax)

    {

        var ownerid1 = ownerid;


        Pet = _db.Pet.Include(pet => pet.Vaccines).FirstOrDefault(pet => pet.PetId == id);


        VaxDateSort = sortOrder == "VaxDate_Asc_Sort" ? "VaxDate_Desc_Sort" : "VaxDate_Asc_Sort";


        IQueryable<Model.Vaccine> vaccine = from s in _db.Vaccine select s;


        switch (sortOrder)

        {

            case "VaxDate_Asc_Sort":

                vaccine = vax.OrderBy(s => s.DateVaccinated);

                break;

            case "VaxDate_Desc_Sort":

                vaccine = vax.OrderByDescending(s => s.DateVaccinated);

                break;

            default:

                vaccine = vax.OrderBy(s => s.DateVaccinated);

                break;

        }

        VaxList = await vax.ToListAsync();


Solution:

I'll start off with a few QoL improvements.


You used 14 lines to describe sorting:

VaxDateSort = sortOrder == "VaxDate_Asc_Sort" ? "VaxDate_Desc_Sort" : "VaxDate_Asc_Sort";


IQueryable<Model.Vaccine> vaccine = from s in _db.Vaccine select s;


switch (sortOrder)

{

    case "VaxDate_Asc_Sort":

        vaccine = vaccine.OrderBy(s => s.DateVaccinated.ToString());

        break;

    case "VaxDate_Desc_Sort":

        vaccine = vaccine.OrderByDescending(s => s.DateVaccinated.ToString());

        break;

    default:

        vaccine = vaccine.OrderBy(s => s.DateVaccinated.ToString());

        break;

}

Vaccine = await vaccine.ToListAsync();


There's something to be said for keeping it like this if you expect multiple sorting methods to be added in the future. However, the devil is in the details:

VaxDateSort = sortOrder == "VaxDate_Asc_Sort" ? "VaxDate_Desc_Sort" : "VaxDate_Asc_Sort";


Why are you making the VaxDateSort the opposite of sortOrder? Why even have a seperate property if you don't mutate it afterwards?


Since VaxDateSort is implied to always have a value, you can add the default switch statement to another case, like:


default:

case "VaxDate_Asc_Sort":

    vaccine = vaccine.OrderBy(s => s.DateVaccinated.ToString());

    break;

Now, you already had some help with fixing some of your other mistakes, so putting it all together with your improved version and fixing the last mistakes you made (vax was the datetime parameter of your method, not the db list), this should let your code compile at least.


I recommend taking a close look at the official MS documentation example of what you're trying to do and cross-referencing >https://learn.microsoft.com/en-us/aspnet/core/razor-pages/?view=aspnetcore-8.0&tabs=visual-studio


using RabiesClinics.Data;

using RabiesClinics.Model;

using Microsoft.AspNetCore.Mvc;

using Microsoft.AspNetCore.Mvc.RazorPages;

using Microsoft.EntityFrameworkCore;


namespace RabiesClinics.Pages.Pets;


[BindProperties]    

public class DetailsModel : PageModel

{

    private readonly ApplicationDbContext _db;


    public Pet Pet { get; set; }

    public Vaccine Vaccine { get; set; }

    public IList<Vaccine> VaxList { get; set; }


    public string VaxDateSort { get; set; }


    public DetailsModel(ApplicationDbContext db)

    {

        _db = db;

    }


    public async Task<IActionResult> OnGetAsync(int ownerid, string id, string sortOrder, DateTime vaxDate)

    {    

        //TODO: inccorporate ownerid and vaxDate as filters

        SelectedPet = _db.Pet

            .Include(pet => pet.Vaccines)

            .FirstOrDefault(pet => pet.PetId == id);


        var vaccines = from s in _db.Vaccine select s;


        if (sortOrder == "VaxDate_Desc_Sort")

            VaxList = await vaccines.OrderByDescending(a => a.DateVaccinated).ToListAsync();

        else

            VaxList = await vaccines.OrderBy(a => a.DateVaccinated).ToListAsync();

                    

        if (Pet is null)

            return new NotFoundResult();

        else

            //TODO: HTML view does not use the Model.Vaccine or Model.VaxList

            return Page();

    }

}


Suggested blogs:

>Step by Step guide to Deploy Terraform in Azure using GitHub Actions

>Testing react components using Hooks and Mocks

>Use Firebase Realtime Database with ASP.NET MVC App

>Use of Singletons in .NET Core in AWS Lambda

>How to do PHP Decryption from Node.js Encryption

>How to Set up the Android emulator?

>How to Set up the local environment for Angular development?

>How to solve encoding issue when writing to a text file, with Python?



Ritu Singh

Ritu Singh

Submit
0 Answers