Posted on:
Categories: SharePoint
Description:

​There are times when I provision a search results web part in a custom site template and need to configure the query programmatically as it changes on a per site basis. The following outlines how I usually go about doing it.

1) In your test site, manually add a Search Results web part to a test page.
2) Manually configure all the web part properties you need including the query.
3) Export the web part to a .webpart file.
4) For best practices, creation of pages including default.aspx should be done in a module outside the custom site template's onet.xml file. In Visual Studio within the module where you provision the page to contain the web part, add an AllUsersWebPart and copy and paste the .webpart file content to it. For example:

<Module Name="Home" Url="$Resources:osrvcore,List_Pages_UrlName;">
<File Url="default.aspx" Type="GhostableInLibrary" Level="Published" Path="PagesModule\default.aspx" >
  <Property Name="Title" Value="$Resources:cmscore,IPPT_HomeWelcomePage_Title;" />
  <Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/masterpage/WelcomeLinks.aspx, $Resources:cmscore,PageLayout_WelcomeLinks_Title;" />
  <Property Name="ContentType" Value="$Resources:cmscore,contenttype_welcomepage_name;" />
  <AllUsersWebPart WebPartZoneID="MainZone" WebPartOrder="1">
 <![CDATA[
   <webParts>
  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
    <metaData>
   <type name="Microsoft.Office.Server.Search.WebControls.ResultScriptWebPart, Microsoft.Office.Server.Search, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
   <importErrorMessage>Cannot import this Web Part.</importErrorMessage>
    </metaData>
    <data>
   <properties>
     ...
     ...
   </properties>
    </data>
  </webPart>
   </webParts> 
 ]]>
  </AllUsersWebPart>
</File>
</Module>
 
5) You would now need a feature receiver to configure the query. Within the feature receiver FeatureActivated event, create a DataProviderScriptWebPart object and set the DataProviderJSON property to the value of the same property from the Search Result web part. Override the QueryTemplate property value, or any other property values like SourceName, SourceID etc. if so desired. For example: 

private void ConfigureSearchResultsWebPart(SPFile pageFile)
{
 using (var lwpm = pageFile.GetLimitedWebPartManager(PersonalizationScope.Shared))
 {
  var webParts = lwpm.WebParts;
  var resultScriptWebPart =
   webParts.Cast()
    .FirstOrDefault(
     wp => wp is ResultScriptWebPart) as ResultScriptWebPart;
  if (resultScriptWebPart == null)
  {
   return;
  }

  var querySettings = new DataProviderScriptWebPart
  {
   PropertiesJson = resultScriptWebPart.DataProviderJSON
  };

  querySettings.Properties["QueryTemplate"] = String.Format("path:\"{0}\" IsDocument:\"True\"", pageFile.Web.Url);
  resultScriptWebPart.DataProviderJSON = querySettings.PropertiesJson;
  lwpm.SaveChanges(resultScriptWebPart);
 }
}