MOSS Document Search Provider For IE8
This post is following the previous one.
In this post I will demonstrate the second search provider for MOSS – the documents search provider for IE8.
I will be using the same solution, using the same method so this time I will only demonstrate the changes between the two. (The HTML is the same HTML from the previous post)
The service
The interface looks like this:
[ServiceContract]
public interface IDocumentSearchService
{
[OperationContract]
[WebGet(UriTemplate = "/Search?q={word}",
BodyStyle = WebMessageBodyStyle.Bare)]
[XmlSerializerFormat]
SearchSuggestion Search(string word);
}
Same as before, a single method with a single parameter.
The Implementation:
public class DocumentSearchService : IDocumentSearchService
{
private XmlDocument xmlIconDoc;
#region IDocumentSearchService Members
public SearchSuggestion Search(string word)
{
xmlIconDoc = new XmlDocument();
xmlIconDoc.Load(@"C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\TEMPLATE\XML\DOCICON.XML");
var oFrt = new FullTextSqlQuery(new SPSite(ConfigurationManager.AppSettings["server"]));
oFrt.QueryText = string.Format(ConfigurationManager.AppSettings["DocumentsSearchQuery"].Replace('@', '"'), word);
oFrt.ResultTypes = ResultType.RelevantResults | ResultType.SpecialTermResults;
oFrt.StartRow = 0;
oFrt.RowLimit = 10;
oFrt.TrimDuplicates = true;
ResultTableCollection lstResults = null;
lstResults = oFrt.Execute();
var ds = new DataSet();
ds.Tables.Add("results");
ds.Tables["results"].Load(lstResults[ResultType.RelevantResults]);
var results = new SearchSuggestion();
results.Query = word;
foreach (DataRow row in ds.Tables["results"].Rows)
{
{
results.Section.Add(new Item
{
Text = row["title"] + " , " + row["Author"] ,
Description =
StripTagsRegex(row["hithighlightedsummary"].ToString()),
Url = row["path"].ToString(),
Image = new Image()
{ Source = GetIcon(row["FileExtension"].ToString()),
Height=16, Width=16 }
});
}
}
return results;
}
static string StripTagsRegex(string text)
{
return Regex.Replace(text, "<.*?>", string.Empty);
}
private string GetIcon(string p)
{
try
{
if (xmlIconDoc.SelectSingleNode("//DocIcons/ByExtension/Mapping[@Key='" + p.ToLower() + "']") != null)
return ConfigurationManager.AppSettings["server"] +
"/_layouts/images/" +
xmlIconDoc.SelectSingleNode("//DocIcons/ByExtension/Mapping[@Key='" +
p.ToLower() +
"']").Attributes["Value"].Value;
else
return ConfigurationManager.AppSettings["server"] +
"/_layouts/images/" +
xmlIconDoc.SelectSingleNode("//DocIcons/Default/Mapping").Attributes["Value"].Value;
}
catch (Exception ex)
{
return ex.Message;
}
}
#endregion
}
As you can see this implementation is a little bit trickier.
The query itself runs the same (different query of course), so does the building of the XML response.
Two main differences are:
1. I’m using StripTagsRegex method to remove tags from the search results because some of them are retuned with internal tagging. (the hithighlightedsummary field)
As for the Image, I’m calling the GetIcon method which uses MOSS internal xml file for mapping file extensions and icons. I’m doing it this way so the user will have the exact same experience he gets while searching inside the portal.
The file is usually located at:
C:\Program Files\Common Files\microsoft shared\Web Server Extensions\12\TEMPLATE\XML\DOCICON.XML
Depends on how you installed the server.
This is a part of the file, just so you’ll know how the mapping goes:
(This file is usually manually altered when installing new IFilters)
The XML defining the service
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>Documents Search</ShortName>
<Url
type="text/html"
template="http://doron-g/searchcenter/Pages/Results.aspx?k={searchTerms}"
/>
<Url
type="application/x-suggestions+xml"
template="http://localhost:52985/SearchProviders/DocumentSearchService.svc/Search?q={searchTerms}"
/>
<Image
height="16"
width="16"
type="image/icon">http://www.netwise.co.il/Images/favicon.ico
</Image>
</OpenSearchDescription>
Same as before, two URL’s, one for redirecting when the user hits Enter and one for the service itself.
The client side script can be found in the previous post.
Adding the provider:
Clicking the second button opens the add search providers dialog:
(Notice the Name label - “Document Search”)
After adding the new provider it is now available in the search providers box, along with our people search provider and any other provider we have installed:
Selecting the documents search provider and typing a phrase will result a list of documents on the server which contains the phrase:
Hitting Enter will redirect me to the default search results page on my portal:
Clicking one of the search results in the providers search results will directly open the file without the need to actually navigate to the portal:
The entire solution can be downloaded from here.