“sgen.exe” exited with code 1

What? I moved my project to my development server and wanted to build for production and this error came up.

What is sgen.exe anyway? I found the answer on msdn: “The XML Serializer Generator creates an XML serialization assembly for types in a specified assembly in order to improve the startup performance of a XmlSerializer when it serializes or deserializes objects of the specified types.”

Hmm… I’m not sure my assembly will be XML serialized. Ever. Then what can I do about it?

Apparently there is a bug in the Visual Studio 2005 for some assemblies when building in release mode. The solution is to disable the generation of the serialization assembly:

  • Open the project properties
  • Go to the “build” tab
  • Find the “Generate serialization assembly” drop-down and choose “Off”

This solved the problem.

Fix to "sgen.exe" exited with code 1 problem

sgen.exe exited with code 1 fix: disable it :-)

Applying datasource to sublayouts on Sitecore items

In Sitecore you can apply a datasource to a sublayout when adding it to a template/item. But the datasource is not automatically used. Your context will not change to the item specified in the datasource.
The datasource is therefore not used as a context change – but it can be. All you need is to use the brilliant code provided by Alexey Rusakov and alter it a bit.

Here is my thoughts: I apply a sublayout to a page. I then alter the datasource because I want the sublayout to get it’s data from another item than the current one.
First I have rewritten the code from Alexey into a function that will return the RenderingDefinition from a specific sublayout on the current item for the current context. All you need is the path to the sublayout in question:

using Sitecore.Layouts;
using Sitecore.Data.Items;

private RenderingDefinition GetRenderingDefinition(string path)
{
  // Get the Layout definition from the current item
  string rend = Sitecore.Context.Item.Fields["__renderings"].Value;
  LayoutDefinition layout = LayoutDefinition.Parse(rend);
  // Get the current device definition
  DeviceDefinition device = layout.GetDevice(Sitecore.Context.Device.ID.ToString());
  // Get the sublayout to find
  Item mySublayout = Sitecore.Context.Database.Items[path];
  // Get the definition for the sublayout
  RenderingDefinition rendering = device.GetRendering(mySublayout.ID.ToString());
  return rendering;
}

I can then use the RenderingDefinition to get the item that the datasource is pointing to. If there is no datasource it means that no datasource have been applied and I’ll use the current item:

private Item GetCurrentItem()
{
  RenderingDefinition def = GetRenderingDefinition("/sitecore/layout/Sublayouts/MySubLayout");
  if (def.Datasource == String.Empty)
    return Sitecore.Context.Item;
  Item dataSourceItem = Sitecore.Context.Database.GetItem(def.Datasource);
  Sitecore.Diagnostics.Assert.IsNotNull(dataSourceItem, "Could not find datasource item at " + def.Datasource);
  return dataSourceItem;
}

In my codebehind for the sublayout I use the item returned by the GetCurrentItem() function instead of the Sitecore.Context.Item, and voila! I have my context change.

BTW: The RenderingDefinition contains much more than the datasource. You can also get the parameters, placeholder and caching informations.
Subnote: Alexey Rusakov describes on his blog that in Sitecore 6 you can use the Attributes["sc_parameters"] to get the parameters for a sublayout. That’s true, but the parameters does not contain the datasource, only the parameters.

Poor performance with sc:IsItemOfType()

Sitecore 6 introduced a new XSLT helper function, IsItemOfType() that will determine if your item descends from a certain type.

This is a very cool and very usefull function when developing component based websites where each page descends from different components identifying if the page has certain properties.

Unfortunately the function suffers from very bad performance which makes it useless in list iterations. See the following example that iterates over all subitems of an item and returns only those who inherits from the “News” template, identifying that the item is a news item:

<xsl:for-each select="$newsRoot//item[sc:IsItemOfType('News',.)]">
  <xsl:sort select="sc:fld('News_Date',.)" data-type="text" order="descending"/>
  <!-- Here I do my stuff with the items -->
  <!-- Render time: 93.000 ms -->
</xsl:for-each>

The list contains 1057 news items in about 20 subfolders. With the above code the list takes 93 seconds(!) to render on my local machine.

Let’s try a new solution. I change the code to use @template=’news’ instead:

<xsl:for-each select="$newsRoot//item[@template='news']">
  <xsl:sort select="sc:fld('News_Date',.)" data-type="text" order="descending"/>
  <!-- I now use the @template='news' to get my news items -->
  <!-- instead of the sc:IsItemOfType() -->
  <!-- Render time: 139 ms -->
</xsl:for-each>

The list now takes 139 ms to render, which is approximately 669 times faster. The disadvantage by using @template=’news’ is obvious. My items has to be of that exact template, not inheriting from it.

There is another solution, and that is to use the sc:GetItemsOfType() function which will return all items from an iterator descending from a specific template:

<xsl:for-each select="sc:GetItemsOfType('News',$newsRoot//item)">
  <xsl:sort select="sc:fld('News_Date',.)" data-type="text" order="descending"/>
  <!-- I get the same list as the other 2 examples -->
  <!-- and I do the same things --> 
  <!-- Render time: 515 ms -->
</xsl:for-each>

This takes 515 ms, which is still 3.7 times slower than the @template=’news’ version. 515 ms could be acceptable in situations where the list can be cached. I would still recommend the middle version using the @template=’news’ for large lists. Using IsItemOfType() and GetItemsOfType() can be used for smaller lists (0-100 items probably) where the performance loss is not that visible.