Search code examples
asp.netpostmodel-view-controllerget

Asp.Net MVC Controller keeps adding values to URL


I'm trying to get my table in the index view filtered by certain values, for this I use a [HttpGet] Index method which creates 2 selectLists (one for each filter type). The filter button is supposed to take the the selected value of each list, and send them to the [HttpPost] Index method, which filters the table.
The problem is that that it doesn't "reset" the url when I filtered, so it keeps adding to the url everytime I change the filter.

Index Get (This one works fine)

        [HttpGet]
        public IActionResult Index()
        {
            IEnumerable<Lesson> Lessons = _LessonRepository.GetAll();
            ViewData["Types"] = GetTypesAsSelectList();
            ViewData["Difficulties"] = GetDifficultiesAsSelectList();
            return View(Lessons);
        }

Index Post (This one keeps adding /Lesson/Index everytime I click the filter button in my view)

       [HttpPost]
        public IActionResult Index(string filter, string filter2)
        {
            IEnumerable<Les> Lessons = null;
            if (filter == null && filter2 == null)
                Lessons = _LessonRepository.GetAll();
            else if (filter != null && filter2 == null)
            {
                Lessons = _LessonRepository.GetByDifficulty(filter);
            }
            else if (filter == null && filter2 != null)
            {
                Lessons = _LessonRepository.GetByType(filter2);
            }
            else if (filter != null && filter2 != null)
            {
                Lessons = _LessonRepository.GetByType(filter2).Where(l => l.Difficulty == filter);
            }
            ViewData["Types"] = GetTypesAsSelectList();
            ViewData["Difficulties"] = GetDifficultiesAsSelectList();
            return View(Lessons);
        }

View

<form action="Lesson/Index/" method="post">
    <div class="form-inline">
        <select id="difficulties" name="filter" asp-items="@ViewData["Difficulties"] as List<SelectListItem>" class="form-control">
            <option value="">-- Select difficulty --</option>
        </select>

        <select id="types" name="filter2" asp-items="@(ViewData["Types"] as List<SelectListItem>)" class="form-control">
            <option value="">-- Select type --</option>
        </select>
        <button type="submit">Filter</button>
    </div>
</form>

Solution

  • This happens because action attribute in form tag contains relative url. The resulting url of request is current url + relative url and that's why Lesson/Index/ is appended to current url on request. Consider using absolute url by adding / at the beggining

    <form action="/Lesson/Index/" method="post">
    

    Since you are using ASP.NET Core you can also make use of asp-action and asp-controller

    <form asp-action="Index" asp-controller="Lesson" method="post">
    

    Or you can stick with relative url but you need to consider how the resulting url is built. So if you form is on /Lesson/Index view then can use the following action

    <!-- empty action, or you can just remove the attribute completely -->
    <form action="" method="post"> 
    

    This will give you current url + relative url = "/Lesson/Index" + "" = "/Lesson/Index"