'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:

enter image description here

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