Monday, December 27, 2010

EasySearch - “The XSLT stylesheet could not be loaded”

Right before christmas I got a “The XSLT stylesheet could not be loaded” error message from the EasySearch FacetCollection control on a customers test server. This confused me quite a lot as the FacetCollection control had worked without problems a couple of days earlier.

The first thing that came to mind when seeing this error message was access rights. Maybe the file permissions had been changed after the last deploy to the server? I checked this, and the file permissions were fine. So I checked the MIME types for .xsl and .xslt, but they were also correct. I suddenly realized that I was able to access the XSLT stylesheets by their url’s on the server, which meant that there had to be an access issue somewhere.

Unfortunately, I couldn’t find it. And to make matters worse, I couldn’t find the piece of code that returned the error message. So I ended up sending an email to NetworkedPlanet support. After asking me to check my file permissions (duh…), they found the issue.

The site was using Basic authentication! We had changed from Windows to Basic authentication a couple of days earlier, but apparently this line in the AbstractXmlControl.cs returns a HTTP 401 – Unauthorized exception if the site uses Basic authentication:

ret.Load(targetUri.ToString(), null, resolver);

Luckily, the site is supposed to use Windows authenication, so we simply switched back.

If you need to use Basic authentication, you can solve this issue by adding the XSLT stylesheet in the code behind:

FlatListFacet.XslStylesheet = File.ReadAllText(pathToXslt);

I’d like to thank the NetworkedPlanet support team for great service and resonse time!

Tuesday, December 7, 2010

EasySearch – Creating a custom index handler

Lately, I’ve spent quite a lot of time figuring out EasySearch. There is a developer guide available, but sadly it is quite messy and brief. So in this blog post I’ll show you how to create a custom index handler in order to add a creation year field to your Lucene document.

The first thing we need to do is to create a custom index handler class. This class needs to inherit from the NetworkedPlanet.EasySearch.Lucene.IIndexHandler interface, which means it needs two methods: IndexFile(…) and IndexPage(…):

public class CustomIndexHandler : IIndexHandler

{

  public CustomIndexHandler(){}

  public bool IndexPage(PageData page, Document luceneDoc)

  {

    AddYearField(page, luceneDoc);

    return true; // returns true, because this method should never block the indexing of a file

  }

 

  public bool IndexFile(UnifiedFile file, Document luceneDoc)

  {

    return true; // returns true, because this method should never block the indexing of a file

  }

 

  private void AddYearField(PageData page, Document luceneDoc)

  {

    // Add the last modified date of the file to a field named

    // "modified". Use a field that is indexed (i.e., searchable),

    // but don't tokenize the field into words.

    luceneDoc.Add(new Field("creationYear", DateTools.TimeToString(page.Created.Ticks, DateTools.Resolution.YEAR), Field.Store.YES, Field.Index.UN_TOKENIZED));

  }

}

The AddYearField adds a new “creationYear” field to the Lucene document. This field is given a year value, such as 2008, 2009, 2010. In order to invoke the index handler before the Lucene document is indexed in Lucene we need to register it in the <indexconfiguration> section in web.config:

<lucene:configuration>

  <lucene:indexhandler Type="MyProject.CustomIndexHandler, MyProject"/>

</lucene:configuration>

It’s as easy as that! You can now use the creationYear field in the Lucene document in a facet or in any other way you need.

Happy coding!