In this article, we'll walk through the process of implementing a global search feature in an ASP.NET Core MVC application. This feature will include a drop-down filter to search through all categories, products, and specific categories or products, and it will display search results with images. Additionally, we'll implement detailed views for the search results, ensuring a complete end-to-end functionality.
Prerequisites
Before we begin, ensure you have the following prerequisites.
- Visual Studio 2019 or later
- .NET Core 3.1 or later
- Basic knowledge of ASP.NET Core MVC
- An existing ASP.NET Core MVC project
Step 1. Setup Database and Models
First, we'll create our database context and models. In this example, we'll have two models: Product and Category.
Models
Create the Product and Category models in the Models folder.
namespace GlobalSearchInAspNetCoreMVC.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string? Description { get; set; }
public string ImageUrl { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
}
}
namespace GlobalSearchInAspNetCoreMVC.Models
{
public class Category
{
public int Id { get; set; }
public string? Name { get; set; }
}
}
namespace GlobalSearchInAspNetCoreMVC.Models
{
public class SearchResultItem
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public string? ImageUrl { get; set; }
}
}
Database Context
Create the ApplicationDbContext in the Data folder.
using GlobalSearchInAspNetCoreMVC.Models;
using Microsoft.EntityFrameworkCore;
namespace GlobalSearchInAspNetCoreMVC.Data
{
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Product> Products { get; set; }
public DbSet<Category> Categories { get; set; }
}
}
Step 2. Create and Seed the Database
Configure the database connection string in appsettings.json.
{
"ConnectionStrings": {
"DefaultConnection": "Data Source=SQLLiteDatabase.db"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Update the Startup. cs or Program. cs to use the ApplicationDbContext.
using GlobalSearchInAspNetCoreMVC.AppService;
using GlobalSearchInAspNetCoreMVC.Data;
using GlobalSearchInAspNetCoreMVC.IAppServices;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddScoped<ISearchService, SearchService>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
app.Run();
Create a migration and update the database.
add-migration GlobalSearch
update-database
Seed the Database
Create a DataSeeder class to seed the database with initial data.
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
namespace GlobalSearchInAspNetCoreMVC.Data
{
public static class DataSeeder
{
public static void Seed(IServiceProvider serviceProvider)
{
using (var context = new ApplicationDbContext(
serviceProvider.GetRequiredService<DbContextOptions<ApplicationDbContext>>()))
{
if (!context.Products.Any())
{
context.Products.AddRange(
new Product { Name = "Product 1", Description = "Description 1", ImageUrl = "/images/product1.jpg" },
new Product { Name = "Product 2", Description = "Description 2", ImageUrl = "/images/product2.jpg" }
);
context.SaveChanges();
}
if (!context.Categories.Any())
{
context.Categories.AddRange(
new Category { Name = "Category 1" },
new Category { Name = "Category 2" }
);
context.SaveChanges();
}
}
}
}
}
Or save the data using a database query.
-- Insert dummy data into Categories table
INSERT INTO Categories (Name)
VALUES
('Electronics'),
('Books'),
('Clothing'),
('Home & Kitchen'),
('Sports & Outdoors');
-- Insert dummy data into Products table
INSERT INTO Products (Name, Description, ImageUrl, CategoryId)
VALUES
('Smartphone', 'Latest model smartphone with advanced features', 'https://via.placeholder.com/150/0000FF/808080?text=Smartphone', 1),
('Laptop', 'High performance laptop suitable for gaming and work', 'https://via.placeholder.com/150/FF0000/FFFFFF?text=Laptop', 1),
('Headphones', 'Noise-cancelling over-ear headphones', 'https://via.placeholder.com/150/FFFF00/000000?text=Headphones', 1),
('Science Fiction Book', 'A gripping science fiction novel', 'https://via.placeholder.com/150/00FF00/000000?text=Science+Fiction+Book', 2),
('Cookbook', 'Delicious recipes for home cooks', 'https://via.placeholder.com/150/FF69B4/000000?text=Cookbook', 2),
('T-shirt', 'Comfortable cotton T-shirt', 'https://via.placeholder.com/150/800080/FFFFFF?text=T-shirt', 3),
('Jeans', 'Stylish denim jeans', 'https://via.placeholder.com/150/FFA500/FFFFFF?text=Jeans', 3),
('Blender', 'High-speed blender for smoothies and soups', 'https://via.placeholder.com/150/000080/FFFFFF?text=Blender', 4),
('Coffee Maker', 'Programmable coffee maker with timer', 'https://via.placeholder.com/150/FFC0CB/000000?text=Coffee+Maker', 4),
('Yoga Mat', 'Non-slip yoga mat for all types of exercise', 'https://via.placeholder.com/150/008080/FFFFFF?text=Yoga+Mat', 5),
('Dumbbells', 'Set of adjustable dumbbells', 'https://via.placeholder.com/150/000000/FFFFFF?text=Dumbbells', 5);
Call the seeder in the Program. cs.
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<ApplicationDbContext>();
context.Database.Migrate();
DataSeeder.Seed(services);
}
host.Run();
}

Pasupathy TPosted Jul 30, 2025, 12:10 PM
What to do if i need to search across 100 model entity