Razor Page Linked Dropdowns
Source Code: https://git.fhict.nl/I872272/RazorPageLinkedDropdown
Hosted Version: https://app8i872272.luna.fhict.nl/
This project demonstrates three different approaches to implementing cascading/linked dropdowns in ASP.NET Core Razor Pages. Each approach has its own advantages and use cases.
Overview
The application implements cascading dropdowns for selecting car Makes and Models:
- Make dropdown: Initially populated with car makes (Toyota, Honda, Ford, BMW, Mercedes-Benz)
- Model dropdown: Dynamically populated based on the selected Make
Three Implementation Techniques
1. Basic AJAX with jQuery (/BasicCascading)
Location: Pages/BasicCascading.cshtml and Pages/BasicCascading.cshtml.cs
Description: A straightforward implementation using jQuery AJAX calls to fetch data asynchronously without page reloads.
How it works:
- The Make dropdown is populated server-side on initial page load
- When a Make is selected, jQuery makes an AJAX GET request to
/BasicCascading?handler=Models - The server returns JSON data with the models for the selected make
- JavaScript dynamically populates the Model dropdown without page refresh
Key Features:
- ✅ No page reloads (smooth user experience)
- ✅ Fast and responsive
- ✅ JSON data transfer (lightweight)
- ❌ Requires jQuery dependency
- ❌ JavaScript code embedded in the page (less reusable)
Files:
Pages/BasicCascading.cshtml- Main page with inline JavaScriptPages/BasicCascading.cshtml.cs- PageModel withOnGetModelshandler
Code Example:
$.ajax({
url: '/BasicCascading?handler=Models',
type: 'GET',
data: { make: selectedMake },
success: function(models) {
// Populate dropdown
}
});
2. PartialViews with AJAX/jQuery (/CascadingDropdowns)
Location: Pages/CascadingDropdowns.cshtml and related partial views
Description: A modular approach using PartialViews for UI components and a separate script partial for JavaScript logic.
What is a Partial View?
A partial view (also called a partial) is a Razor view file (.cshtml) that contains reusable HTML markup and Razor syntax. Unlike a full page, a partial view:
- Cannot be accessed directly via a URL (no
@pagedirective) - Is rendered within another view or page
- Promotes code reusability and separation of concerns
- Typically starts with an underscore (
_) in the filename (e.g.,_MakeDropdownPartial.cshtml)
Benefits of Partial Views:
- Reusability: Write once, use in multiple pages
- Modularity: Break complex pages into smaller, manageable components
- Maintainability: Update a component in one place, affects all usages
- Testability: Easier to test individual components
- Organization: Keep related markup together
How to Use Partial Views:
@await Html.PartialAsync("PartialName", modelData)
The first parameter is the partial view name (without .cshtml extension), and the optional second parameter is the model/data to pass to the partial.
How it works:
- UI components are separated into reusable partial views:
_MakeDropdownPartial.cshtml- Make dropdown component_ModelDropdownPartial.cshtml- Model dropdown component_CascadingDropdownScriptsPartial.cshtml- JavaScript logic
- The main page composes these partials together
- Uses the same AJAX/jQuery approach as Technique #1, but with better code organization
Key Features:
- ✅ Modular and reusable components
- ✅ Separation of concerns (UI, logic, scripts)
- ✅ No page reloads
- ✅ Easy to maintain and test
- ❌ Still requires jQuery dependency
- ❌ Uses JSON responses
Files:
Pages/CascadingDropdowns.cshtml- Main pagePages/CascadingDropdowns.cshtml.cs- PageModelPages/Shared/_MakeDropdownPartial.cshtml- Make dropdown partialPages/Shared/_ModelDropdownPartial.cshtml- Model dropdown partialPages/Shared/_CascadingDropdownScriptsPartial.cshtml- JavaScript partial
Code Example:
@await Html.PartialAsync("_MakeDropdownPartial", Model.Makes)
@await Html.PartialAsync("_ModelDropdownPartial")
3. Traditional Form Submission with PartialViews (/TraditionalCascading)
Location: Pages/TraditionalCascading.cshtml and related partial views
Description: A server-side approach using traditional form POST requests with full page reloads. No jQuery or JSON required.
How it works:
- Uses a standard HTML form with POST method
- When a Make is selected, vanilla JavaScript automatically submits the form
- The server processes the POST request in
OnPost(string selectedMake)handler - The server returns the full page with the Model dropdown populated server-side
- The selected Make is preserved through the form submission
Key Features:
- ✅ No JavaScript dependencies (works without jQuery)
- ✅ No JSON responses (pure HTML)
- ✅ Server-side rendering (better for SEO)
- ✅ Works even if JavaScript is disabled (with submit button)
- ✅ Simpler architecture
- ❌ Full page reloads (less smooth UX)
- ❌ More server round-trips
Files:
Pages/TraditionalCascading.cshtml- Main page with formPages/TraditionalCascading.cshtml.cs- PageModel withOnPosthandlerPages/Shared/_TraditionalMakeDropdownPartial.cshtml- Make dropdown partialPages/Shared/_TraditionalModelDropdownPartial.cshtml- Model dropdown partialPages/Shared/_TraditionalCascadingScriptsPartial.cshtml- Vanilla JavaScript for auto-submit
Code Example:
public void OnPost(string selectedMake)
{
Makes = CarData.GetMakes();
SelectedMake = selectedMake;
Models = CarData.GetModels(selectedMake);
}
// Vanilla JavaScript (no jQuery)
makeDropdown.addEventListener('change', function() {
form.submit();
});
Comparison Table
| Feature | Technique 1 (Basic AJAX) |
Technique 2 (Partials + AJAX) |
Technique 3 (Traditional Form) |
|---|---|---|---|
| Page Reloads | ❌ No | ❌ No | ✅ Yes |
| jQuery Required | ✅ Yes | ✅ Yes | ❌ No |
| JSON Responses | ✅ Yes | ✅ Yes | ❌ No |
| Modularity | ❌ Low | ✅ High | ✅ High |
| Reusability | ❌ Low | ✅ High | ✅ High |
| User Experience | ✅ Excellent | ✅ Excellent | ⚠️ Good |
| SEO Friendly | ⚠️ Moderate | ⚠️ Moderate | ✅ Excellent |
| JavaScript Disabled | ❌ No | ❌ No | ✅ Yes* |
| Complexity | ⚠️ Medium | ⚠️ Medium | ✅ Low |
*With a submit button fallback
Data Model
All three techniques use the same data source: Models/CarData.cs
public static class CarData
{
// Makes: Toyota, Honda, Ford, BMW, Mercedes-Benz
// Models vary by Make
}
When to Use Each Technique
Use Technique 1 (Basic AJAX) when:
- You need a quick, simple solution
- Code reusability is not a priority
- You're already using jQuery in your project
Use Technique 2 (Partials + AJAX) when:
- You want modular, maintainable code
- You need reusable UI components
- You want the best user experience with AJAX
- You're building a larger application
Use Technique 3 (Traditional Form) when:
- You want to avoid JavaScript dependencies
- SEO is important
- You need to support users with JavaScript disabled
- You prefer server-side rendering
- Simplicity is a priority
Running the Application
- Navigate to the project directory
- Run
dotnet restore(if needed) - Run
dotnet run - Open your browser to the URLs shown in the console (typically
https://localhost:5001orhttp://localhost:5000)
Navigation
The application includes navigation links to all three examples:
- Home (
/Index) - Overview and documentation - Basic Cascading (
/BasicCascading) - Basic AJAX implementation - Cascading Dropdowns (
/CascadingDropdowns) - PartialViews with AJAX - Traditional Cascading (
/TraditionalCascading) - Traditional form submission
Technologies Used
- ASP.NET Core 8.0
- Razor Pages
- jQuery (for Techniques 1 & 2)
- Vanilla JavaScript (for Technique 3)
- Bootstrap 5 (for styling)
Notes
- All three techniques use the same underlying data (
CarDataclass) - The partial views in Technique 3 avoid using
@modeldirectives to prevent conflicts with Razor's model directive - Technique 3 uses variable name
carModelinstead ofmodelin loops to avoid conflicts with Razor's@modeldirective