简体   繁体   中英

Creating Cascading dropdown in asp.net core with razor pages not working

I'm trying to implement a cascading dropdown list with asp.net core 3.1 code first. I have two tables which are vehicle make and vehicle model. the first dropdown would populate the makes and on selecting any make the second dropdown would populate the models. but I keep getting undefined on the model dropdown. below is my implementation. please what am I doing wrong? thanks

IVehicleService interface

    
    namespace Application.Common.Interfaces
    {
       public interface IVehicleService
       {
         IEnumerable<VehicleMake> GetMakes();
         IEnumerable<VehicleModel> GetModels(int categoryId);
       }
     }

Vehcicle Service


    namespace Application.Common.Interfaces
    {
      public class VehcicleService : IVehicleService
      {
        private readonly IApplicationDbContext _dbContext;
        public VehcicleService(IApplicationDbContext dbContext)
        {
            _dbContext = dbContext;
        }
        public IEnumerable<VehicleMake> GetMakes()
        {
            IEnumerable<VehicleMake>  makes = _dbContext.VehicleMakes.ToList();
            return makes;       
        }
        public IEnumerable<VehicleModel> GetModels(int MakeId)
        {
            IEnumerable<VehicleModel> model = _dbContext.VehicleModels.Where(x => x.VehicleMakeId == MakeId).ToList();            
            return model;
        }
    }
     }

My Model Page

namespace Wbc.WebUI.Areas.Tools.Pages
{
    
    public class SearchByMakeModel : PageModel
    {
       private readonly IVehicleService _vehicleService;
        public SearchByMakeModel(IVehicleService vehicleService)
        {           
            _vehicleService = vehicleService;
        }
        [BindProperty(SupportsGet = true)]
        public int MakeId { get; set; }
        public int ModelId { get; set; }
        public SelectList MakeListdll { get; set; }

       public void OnGet()
        {
            MakeListdll = new SelectList(_vehicleService.GetMakes(), nameof(VehicleMake.Id), 
            nameof(VehicleMake.Name));
        }

        public JsonResult OnGetSubCategories()
        {
            return new JsonResult(_vehicleService.GetModels(MakeId));
        }
    }
}

My Razor Markup

 <select asp-for="MakeId" asp-items="Model.MakeListdll">
   <option value=""></option>
   </select>

   <select asp-for="ModelId">                            
    </select>

The interface and its implementation are registered with the dependency injection system in Startup:

services.AddTransient<IVehicleService, VehcicleService>();

My Ayax Call

@section scripts{
    <script type="text/javascript">
        $(function () {
            $("#MakeId").on("change", function() {
                var makeId = $(this).val();
                $("#ModelId").empty();
                $("#ModelId").append("<option value=''>Select Model</option>");
                $.getJSON(`?handler=OnGetModels&MakeId=${makeId}`, (data) => {
                    $.each(data, function (i, item) {
                        $("#ModelId").append(`<option value="${item.Id}">${item.Name}</option>`);
                    });
                });
            });
        });
    </script>
}

First of all, in $.getJson of js, you need to change the handler to SubCategories , because you need to enter OnGetSubCategories to obtain VehicleModel datas.

but I keep getting undefined on the model dropdown

And another important point is that in core, when ajax returns json, the field name will be changed to camel case by default , so you need to change the first letter of the field name after item to lowercase, such as: ${item.id} and ${item.name} .

Since you did not provide the VehicleModel class, here is my custom VehicleModel class:

   public class VehicleModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int VehicleMakeId { get; set; }
    }

Here is js:

@section scripts{
    <script type="text/javascript">
        $(function () {
            $("#MakeId").on("change", function () {
                var makeId = $(this).val();
                $("#ModelId").empty();
                $("#ModelId").append("<option value=''>Select Model</option>");
                $.getJSON(`?handler=SubCategories&MakeId=${makeId}`, (data) => {
                    $.each(data, function (i, item) {
                        $("#ModelId").append(`<option value="${item.id}">${item.name}</option>`);
                    });
                });
            });
        });
    </script>
}

Update

If you don't want the field name in the returned json to become camel case, then you can add the following statement in the startup to cancel it:

services.AddMvc().AddJsonOptions(jsonOptions =>
        {
            jsonOptions.JsonSerializerOptions.PropertyNamingPolicy = null;
        });

Here is the test result:

在此处输入图像描述

Always check the Network tab in the browser's developer tools when working with AJAX requests. Then you will see that the request is returning 404 Not Found. You have a handler named OnGetSubCategories in the PageModel, but your AJAX call handler parameter is named OnGetModels .

Once you have decided which name you want to use, you should drop the OnGet or OnPost part when passing the name of the handler to the AJAX query string:

$.getJSON(`?handler=Subcategories&MakeId=${makeId}`

Further info on working with named handler methods: https://www.learnrazorpages.com/razor-pages/handler-methods#named-handler-methods

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM