'C# ASP.NET Core Razor page - call PageModel method from inside the Razor page?
Here's my problem: I have a page that has 2 Select elements (dropdowns). The first selects a value, when the first selection changed I want the second dropdown to load values.
I already know that I can use the asp-items property to "bind" values into the dropdown.
I am trying to use the onchange method on the first select element and then in the JS-Script to call a method in the model to load the items.
But I get an error:
Cannot implicitly convert type 'void' to 'object'
This is my html.cs:
<a>Article: </a>
<select name="Articles" id="articles" asp-for="@Model.SelectedArticleTag" asp-items="@Model.ArticlesDropdownItems">
<option value="notChosen">Choose Article...</option>
</select>
<br/>
<a>Article Variant: </a>
<select name="ArticleVariants" id="variants" asp-items="@Model.ArticleVariantsDropdownItems">
<option value="notChosen">Choose Variant...</option>
</select>
This is my html.cs Script section to get the onchange event: (@Model.UpdateVariants(); shows me the error I mentioned at the top)
@section scripts {
<script>
$("#articles").on("change", function () {
@Model.UpdateVariants();
});
</script>
}
And this is my PageModel method I want to call (which doesn't get called):
public void UpdateVariants()
{
string articleNumber = ArticlesDropdownItems[SelectedArticleTag].Value;
var unifiedVariants = LoadVariants(articleNumber).Result.ToList();
ArticleVariantsDropdownItems = unifiedVariants.Select(v => new SelectListItem
{
Value = v.ArticleVariantNumber,
Text = $"{v.ArticleVariantNumber} - {v.ArticleVariantSize} - {v.ArticleVariantPrice}"
}).ToList();
}
What am I doing wrong?
Solution 1:[1]
In the .cshtml page Script section, you can't directly use @Model.UpdateVariants(); to call the handler method. And for the UpdateVariants handler method, you need to return the JsonResult, instead of use void.
To create a Cascading Dropdowns With AJAX in Razor Pages, you could refer the following code:
Code in the .cshtml.cs file:
public class CascadingDropdownsModel : PageModel
{
private ICategoryService categoryService;
public CascadingDropdownsModel(ICategoryService categoryService) => this.categoryService = categoryService;
[BindProperty(SupportsGet = true)]
public int CategoryId { get; set; }
public int SubCategoryId { get; set; }
public SelectList Categories { get; set; }
public void OnGet()
{
//get the category data, and popuplate the first dropdown list.
Categories = new SelectList(categoryService.GetCategories(), nameof(Category.CategoryId), nameof(Category.CategoryName));
}
public JsonResult OnGetSubCategories()
{
//based on the categoryid to find all subcategories, then return them to the view page and populate the second dropdownlist.
return new JsonResult(categoryService.GetSubCategories(CategoryId));
}
}
Code in the .csthml file:
@page
@model RazorAPP.Pages.CascadingDropdownsModel
<h4>Categories</h4>
<select asp-for="CategoryId" asp-items="Model.Categories">
<option value="">Select Category</option>
</select>
<h4>SubCategories</h4>
<select asp-for="SubCategoryId"></select>
@section scripts{
<script>
$(function () {
$("#CategoryId").on("change", function() {
var categoryId = $(this).val();
$("#SubCategoryId").empty();
$("#SubCategoryId").append("<option value=''>Select SubCategory</option>");
$.getJSON(`?handler=SubCategories&categoryId=${categoryId}`, (data) => {
$.each(data, function (i, item) {
$("#SubCategoryId").append(`<option value="${item.subCategoryId}">${item.subCategoryName}</option>`);
});
});
});
});
</script>
}
The result like this:
More detail information, see Cascading Dropdowns With AJAX in Razor Pages.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Zhi Lv |

