in

Dot Net Mafia

Group site for developer blogs dealing with (usually) .NET, SharePoint 2013, SharePoint 2010, Office 365, SharePoint Online, and other Microsoft products, as well as some discussion of general programming related concepts.

This Blog

Syndication

Archives

Corey Roth [MVP]

A SharePoint MVP bringing you the latest time saving tips for SharePoint 2013, Office 365 / SharePoint Online and Visual Studio 2013.

How to: Build a custom advanced search control for Enterprise Search

It’s been a while since I have done a how to post, so I thought it was due time.  I see request all of the time for people wanting to provide very specific custom advanced search capabilities.  The AdvancedSearchWebPart is ugly and bit lacking, but luckily it is quite easy to build your own.  For simplicity of today’s example, I built my custom search as a web user control.  You can easily host this inside a web part by building your own SmartPart (or by using the one on CodePlex).  In my example, I want a search page which lets me do normal keyword searches as well as search by product number and color.  I also want to filter by results using specific scopes.  This search control will go on a page inside the search center and use the existing results.aspx page to display the results.

However, before we begin, we must review a few concepts.  First, to be able to search on a specific field, you must have a managed property mapped to the field.  This applies if you are mapping to a site column or if you are mapping to some column in the database exposed via BDC.  Secondly, you must take note of how the URL Syntax works for Enterprise Search.  The reason for this is that we are simply redirecting the user to the results.aspx page via query string.  This gives us custom functionality while keeping the out of the box search results.  The URL syntax works similarly to the Keyword Syntax using the ‘k’ query string parameter. 

Let’s first review the keyword syntax.  For example, I want to search for anything with the word “Shirt” that is colored red in our “Online Products” scope.  This is what the keyword syntax looks like.

Shirt Color:”Red” Scope:”Online Products”

This same query would be passed to results.aspx, using the ‘k’ query string parameter as such.  You can URL encode it of course if necessary.

results.aspx?k=Shirt Color=”Red” Scope=”Online Products”

Pretty simple, right?  So what does the user control look like?  In my case, I have managed properties called Color and ProductNumber.  Scope already has meaning in keyword syntax so it does not have to be accounted for.

CustomSearch

It’s pretty simple, but allows me to use DropDownLists or whatever user control I want to use on each step.  The code to generate the URL string is quite simple.  You may need to take into account the proper URL to your results.aspx page in your Search Center.

protected void SearchButton_Click(object sender, EventArgs e)

{

    Response.Redirect(GetQueryUrlSyntaxString());

}

/// <summary>

/// Returns a string in the url query syntax.

/// </summary>

/// <returns></returns>

private string GetQueryUrlSyntaxString()

{

    System.Text.StringBuilder queryString = new System.Text.StringBuilder();

    // append the path to results.aspx here

    queryString.Append("results.aspx?k=");

    // append the generic search term, followed by managed properties

    // for example: shirts ProductNumber:"01232"

    // for example: coats Color:"Red" Scope:"Retail Products"

    if (!string.IsNullOrEmpty(SearchTextBox.Text))

        queryString.Append(SearchTextBox.Text);

    // write a space followed by the managed property and the value in quotes i.e.: ProductNumber:"01232"

    if (!string.IsNullOrEmpty(ProductNumberTextBox.Text))

        queryString.AppendFormat(" {0}:\"{1}\"", "ProductNumber", ProductNumberTextBox.Text);

    if (!string.IsNullOrEmpty(ColorDropDownList.SelectedValue))

        queryString.AppendFormat(" {0}:\"{1}\"", "Color", ColorDropDownList.SelectedValue);

    // scope can also be passed on the 's' query string parameter

    if (!string.IsNullOrEmpty(ScopeDropDownList.SelectedValue))

        queryString.AppendFormat(" {0}:\"{1}\"", "Scope", ScopeDropDownList.SelectedValue);

    return queryString.ToString();

}

It simply uses a StringBuilder to assemble a query string as we saw in the above query string syntax.  I’ve also attached the code to this post as a starting point for you.  Hopefully, you will find it useful.  If you are not familiar with how to deploy a user control, use this post.

Comments

 

suggestme said:

Couldn't able to find the attachment. Pls share the sample code.

March 11, 2009 3:46 AM
 

CoreyRoth said:

The attachment is linked at the bottom of this post.  www.dotnetmafia.com/.../859.ashx

March 11, 2009 9:16 AM
 

suggestme said:

Hi Corey,

Will this can be implemented for metadata property search with lookup columns too.

March 12, 2009 11:54 PM
 

Josh said:

Corey: Very informative. But the URL syntax used in the Sharepoint 2010 search centre seems to be different -- it seems to want &s= for scopes, and there's an &r= for refinements.

Any idea where the URL syntax for 2010 is documented?

November 16, 2010 2:54 PM
 

CoreyRoth said:

@Josh I haven't been able to find a link on it.  It's basically the same except the addition of r.  There may be another new parameter I am not thinking of though.

November 22, 2010 5:01 PM
 

C# | Pearltrees said:

Pingback from  C# | Pearltrees

March 2, 2012 4:56 AM
 

Sharada said:

Hi Corey,

We had an advanced webpart which lets user select sites so that search is scoped on the selected sites, we are moving to 2013, i tried using u parameter localhost'test'  but this doesnot meet out requirement which required the search results to filter the results based on multiple result sources selected by user. How can i achive this?  i tried giving multiple values to U parameter but that is not working.

Thanks,

Sharada

July 1, 2013 3:54 AM
 

CoreyRoth said:

@Sharada hmm, I haven't tried that.  I'll see if I can figure it out.

July 16, 2013 10:49 AM
 

Sharada said:

Hi Corey,

Ended up using multi select refiners and used managed metadata to achieve what we wanted, Still i am interested if we can do something like localhost/results.aspx’test’&SourceID=’GUID for result Source1’+GUID for result Source2’  which directs us results.aspx and no need to parse the xml

July 23, 2013 2:02 AM

Leave a Comment

(required)  
(optional)
(required)  
Add

About CoreyRoth

Corey Roth is an independent SharePoint consultant specializing in ECM, Apps, and Search.
2012 dotnetmafia.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems