Search code examples
c#asp.net-coremodel-view-controllerasp.net-core-mvcmodel-binding

Problem paging with multiple criteria in get request .NET MVC Core


I am developing a web app using the Net Core MVC structure. I have a page that is many search criteria and I want to send parameters over URL with getting request. I am using many select components on my view and it can be selected multiple values. I am sending one or multiple values over URL with the request. There is a paging system in my view and after making get request with filter values not retrieving or set values to select components. I am also using Select2 components. Briefly, paging creates a problem retrieving or sending values between view-controller.

[HttpGet]  
    public async Task<IActionResult> TumApartmanlar(long il,long[] ilceler, int? pageNumber)
    {
        ViewData["ilceler"] = ilceler;
        ViewData["il"] = il;
        //Then set to filters

        var sonuc = _apartmanService.ListByFilters(filters, loadImages: true);

        int pageSize = 10;
        TumApartmanlarViewModel tumApartmanlar = new TumApartmanlarViewModel();
        tumApartmanlar.ApartmanListe = PaginatedList<ApartmanListDto>.Create(sonuc, pageNumber ?? 1, pageSize),
       ..... another code part and paging


        return View(tumApartmanlar);
    }

View part:

 <form asp-controller="EndUser" asp-action="TumApartmanlar" method="get">
                <div class="row mt-2">
                    <div class="col-12">
                        <label>İl</label>
                        <select  class="form-control" id="selectIlSec"  asp-for="@ViewData["il"]" name="il"
                                asp-items="@(new SelectList(Model.Iller,"Id","Ad"))">
                            <option></option>
                        </select>
                    </div>

                </div>
                <div class="row mt-2">
                    <div class="col-12">
                        <label>İlçe</label>
                        <select multiple="multiple" class="form-control" disabled="@(Model.ApartmanFilters.IlId>0?false:"disabled")" id="selectIlceSec" 
                                 name="ilceler"  asp-for="@ViewData["ilceler"]" asp-items="@(new MultiSelectList(Model.Ilceler,"Id","Ad"))">
                            <option></option>
                        </select>
                    </div>
                 /*Another components*/
                </div>
               <button type="submit" style="width:100%;" class="btnAra btn btn-md p-2 mt-3 mb-3 btn-danger"> Ara </button>
                

</form>
    @{
        var prevDisabled = !Model.ApartmanListe.HasPreviousPage ? "disabled" : "";
        var nextDisabled = !Model.ApartmanListe.HasNextPage ? "disabled" : "";
    }

   

    <a asp-action="TumApartmanlar"
       asp-route-pageNumber="@(Model.ApartmanListe.PageIndex - 1)"                      
       asp-route-il="@Model.ApartmanFilters.IlId"
       asp-route-ilceler="@(ViewData["ilceler"].ToString())"
       class="btn btn-default @prevDisabled">
        Previous
    </a>


    <a asp-action="TumApartmanlar"           
       asp-route-pageNumber="@(Model.ApartmanListe.PageIndex + 1)"
       asp-route-il="@Model.ApartmanFilters.IlId"
       asp-route-ilceler="@(ViewData["ilceler"].ToString())"
       class="btn btn-default @nextDisabled">
        Next
    </a>

Script part

$("#selectIlSec").select2({
    width: 'resolve',
    placeholder: "İl Seçiniz",
    allowClear: true
});

$("#selectIlceSec").select2({
    width: 'resolve',
    placeholder: "İlçe Seçiniz",
    allowClear: true
});

How can I achieve send multiple selected values when clicking paging buttons? I try asp-for-ilceler but not sending values. Also when clicking the button to get a request, the URL looks like ..../EndUser/TumApartmanlar?il=1&ilceler=1&ilceler=2... Paging can not bind like seperate ilceler. I am waiting for your help, thank you.

UPDATE

My filter class

 public class ApartmanListFilter
 {
    [FromQuery(Name = "il")]
    public long IlId { get; set; }    

    [FromQuery(Name = "ilceler")]
    public List<long> IlceIds { get; set; }
 }

If i use like above, my controller and view is changing like below but i still have a problem.

 [HttpGet]
    public IActionResult Evler([FromQuery]ApartmanListFilter filters)
    {
        var sonuc = _apartmanService.ListByFilters(filters, loadImages: true);
       //Another codes
        return View(sonuc);
    }

<div class="col-12">
    <label>İl</label>
      <select  class="form-control" id="selectIlSec"  asp-for="@Model.ApartmanFilters.IlId" name="il"
    asp-items="@(new SelectList(Model.Iller,"Id","Ad"))">
       <option></option>
        </select>
 </div>

Solution

  • Solution 1

    You can use javasript to jump, the following is an example.

    Take Previous as an example:

    <a class="sort"  href="javascript:void(0)">
    Previous
    </a>
    
    @section scripts{
        <script>
            var [email protected](Json.Serialize((long[])ViewData["ilceler"]));
            $(".sort").click(function () {
                var link = "/EndUser/TumApartmanlar?";
                link += "il=" + 1 +"&";
                c.forEach(function (value) {
                    link += "ilceler=" + value + "&";
                });
                link += "pageNumber=" + 1;
                window.location.href = link;
            })
        </script>
    }
    

    Please note that il and pageNumber are my simulated data, you need to get it in javascript by yourself.

    Test result:

    enter image description here

    Solution 2

    You can change your type long[] to string[],then in your TumApartmanlar:

     [HttpGet]
        public async Task<IActionResult> TumApartmanlar(long il, string[] ilceler, int? pageNumber)
        {
            string ids = String.Join(",", ilceler.Select(p => p.ToString()).ToArray());
            ViewData["ilceler"] = ids;
            ViewData["il"] = il;
    

    Then when you click the a tag, your ilceler will become like string[0]="1,3", you can then process the data into the format you want.

    Test result:

    enter image description here