Click here to Skip to main content
15,663,963 members
Articles / Web Development / ASP.NET
Posted 5 Jan 2012


29 bookmarked

C# Simple Search Class

Rate me:
Please Sign up or sign in to vote.
4.70/5 (9 votes)
5 Jan 2012CPOL2 min read
Simple customizable searching in ASP.NET.

Sample Image


This article introduces some simple code which allows easy addition of search functionality which can be used to search any object (files, .NET classes) and display the search results together in a single view.


This demo is presented in ASP.NET MVC so basic MVC knowledge would be useful, although this solution could be applied to other .NET environments.

Using the Code

The main work is done in the implementations of the abstract base class Searcher. In this example, some dummy data is created in the constructor, this is then queried for matching items in the Search method and projected into a SearchResult. Note how RouteInformation is populated. The entries in the RouteInformation dictionary will be used to create an ActionLink in the MVC view.

public class ProductSearcher : Searcher
    private List<Product> Products { get; set; }

    public ProductSearcher()
        //Dummy up some data here...
        Products = new List<Product>();

    public override IEnumerable<SearchResult> Search(string searchTerm)
        var result = Products.Where(p => p.Description.ToLower().Contains(
                     searchTerm.ToLower()) || 
            .Select(p => new SearchResult
                Category = "Product",
                Description = p.Name,
                Id = p.ProductId,
                OriginatingObject = p

        result.ForEach(p => p.RouteInformation = GetRouteInfo(p.Id));

        return result;

    private static Dictionary<string, string> GetRouteInfo(int id)
        return new Dictionary<string, string>
                                    {"controller", "product"},
                                    {"action", "details"},
                                    {"Id", id.ToString()}

SearchCore is initialized with a List of Searcher implementations that it should use to build the search results. When Search is called, it simply iterates over them, calling their Search method and aggregating the result.

public class SearchCore
    private List<Searcher> Searchers { get; set; }

    public SearchCore(List<Searcher> searchers)
        Searchers = searchers;

    public IEnumerable<SearchResult> Search(string searchTerm)
        var result = new List<SearchResult>();

        foreach (Searcher searcher in Searchers)
        return result;

The Search Controller

The search controller just has a single ActionResult which creates instances of our Searchers and adds them to a list which is then passed to SearchCore. It uses a stopwatch to measure the time taken to perform the search. Caching can be enabled on the Search method to improve performance.

private SearchCore SearchCore { get; set; }

public SearchController()
    var searchers = new List<Searcher> {new ProductSearcher(), new CompanySearcher()};

    SearchCore = new SearchCore(searchers);

//Uncomment below to enable caching.
//[OutputCache(VaryByParam = "searchTerm", Duration = 180)]
public ActionResult Search(string searchTerm)
    var model = new SearchResponse();

    //Use a stopwatch to measure the time it takes to perform the search.
    var s = new System.Diagnostics.Stopwatch();
    model.Results = SearchCore.Search(searchTerm);
    model.OriginalSearchTerm = searchTerm;
    model.TimeTaken = s.Elapsed;
    return View(model);

Search View

The search view simply prints the original search term and time taken, and iterates over the results, printing the link (using the RouteInfoLink extension method) and then calling a DisplayTemplate for the original object (whatever that may be). The Display Templates are stored in the DisplayTemplates subfolder of the Search folder.

@model SimpleSearch.SearchResponse
    <title>Search Results</title>
    <h2>Search Results</h2>
    @Html.Raw(string.Format("Your search for <strong>{0}</strong> returned {1} 
        results in {2} seconds", Model.OriginalSearchTerm, Model.Results.Count(), 
        Math.Round(Model.TimeTaken.TotalSeconds, 3)))<br />
    @*Only meaningful if caching is enabled on the controller*@
    <em>@String.Format("Cached at {0}", DateTime.Now.ToShortTimeString())</em>
    @foreach (var item in Model.Results)
        <section style="border: 0px none; display: block; float: none; padding: 0px">
            <h3>@item.Category - @Html.RouteInfoLink(item.Description, item.RouteInformation)</h3>
            @Html.DisplayFor(m =>

Display Templates

The DisplayTemplates are just standard Razor partials named after the type they are strongly-typed to.

@model Search.Models.Product

<section style="border: 0px none; display:block; float:none; padding: 0px">
    @Model.Name<br />
    <b>Short Name: </b>@Model.ShortName<br/>


Points of Interest

This is only a very basic implementation but shows how you can do really useful things with relatively little code.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Written By
Software Developer
United Kingdom United Kingdom
I have been programming for 10 years, starting with VB6, moving to VB.Net and now primarily working with C# and MVC.

Comments and Discussions

GeneralMy vote of 5 Pin
itaitai10-Jan-12 1:48
professionalitaitai10-Jan-12 1:48 
QuestionMy 5 Pin
Mardani Dani5-Jan-12 23:35
Mardani Dani5-Jan-12 23:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.