<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Blog posts by Tobias Nilsson</title><link href="http://world.optimizely.com" /><updated>2016-03-03T11:08:38.9530000Z</updated><id>https://world.optimizely.com/blogs/Tobias-Nilsson/</id> <generator uri="http://world.optimizely.com" version="2.0">Optimizely World</generator> <entry><title>How to listen to remote Commerce events</title><link href="https://world.optimizely.com/blogs/Tobias-Nilsson/Dates/2016/3/how-to-listen-to-remote-commerce-events/" /><id>&lt;p&gt;This will be a quick tips for people who want to listen to &lt;em&gt;external&amp;nbsp;&lt;/em&gt;Commerce events. I have a perculiar situation where I via the Service API import my products, but the service API isn&#39;t hosted on the same site/server as my site, but on a separate one instead. This means&amp;nbsp;that&amp;nbsp;I can&#39;t&amp;nbsp;listen to local events like I would normally and will have to listen to remote events. But is there such events for Commerce? I know that Episerver sends remote events for cache invalidations, so maybe they send events for Commerce event too.&lt;/p&gt;
&lt;p&gt;To listen to local Commerce events you can create your own implementation of &lt;strong&gt;CatalogEventListenerBase&amp;nbsp;&lt;/strong&gt;and&amp;nbsp;one of the out of the box implementation of this abstract class is the &lt;strong&gt;CatalogEventBroadcaster&lt;/strong&gt;. This class will take the local event and send out remote events that we can listen to! So to solve my problem I implemented the following in a IConfigurableModule.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;	[ModuleDependency(typeof(ServiceContainerInitialization))]
	public class CatalogEventListener : IConfigurableModule
	{
		public void Initialize(EpiserverCommerce.Framework.Initialization.InitializationEngine context)
		{
			Event ev = Event.Get(CatalogEventBroadcaster.CommerceProductUpdated);
			ev.Raised += Ev_Raised;
		}

		private void Ev_Raised(object sender, EpiserverCommerce.Events.EventNotificationEventArgs e)
		{
			if (!(e.Param is Byte[])) return;
			var eventArgs = DeSerialize(e.Param as Byte[]);
			// Care only about catalog entry events
			var catalogEvents = eventArgs as CatalogContentUpdateEventArgs;
			if (catalogEvents == null || !catalogEvents.CatalogEntryIds.Any()) return;

			switch (catalogEvents.EventType)
			{
				case Mediachase.Commerce.Catalog.Events.CatalogEventBroadcaster.CatalogEntryUpdatedEventType:
					catalogEvents.CatalogEntryIds.ForEach(entryId =&amp;gt; UpdateIndex(entryId));
					break;
				default:
					break;
			}
		}

		private static EventArgs DeSerialize(byte[] buffer)
		{
			var formatter = new BinaryFormatter();
			using (var stream = new MemoryStream(buffer))
			{
				return formatter.Deserialize(stream) as EventArgs;
			}
		}		
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Big thanks to Quan Mai for helping me find the right class!&lt;/p&gt;</id><updated>2016-03-03T11:08:38.9530000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>An Example Product Level Pricing Provider</title><link href="https://world.optimizely.com/blogs/Tobias-Nilsson/Dates/2015/4/an-example-product-level-pricing-provider/" /><id>&lt;h3&gt;&lt;span&gt;Introduction&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;For some e-Commerce projects out there it might be more logical to store the prices on a product level than to store it on the variants. One example is clothing stores. A T-Shirt product might have four different sizes but they all cost the same. Then it makes sense to store the price on the product level instead of on the variant level.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Out of the box EPiServer Commerce UI only supports storing the prices on the variant level by using the default &lt;a href=&quot;/link/55fe410f4f65482cab72fb59d47c7561.aspx?id=66786&amp;amp;documentId=commerce/7.5/885DC505&quot;&gt;&lt;span&gt;IPriceDetailService&lt;/span&gt;&lt;/a&gt; and &lt;a href=&quot;/link/55fe410f4f65482cab72fb59d47c7561.aspx?id=66786&amp;amp;documentId=commerce/7.5/301C04E6&quot;&gt;&lt;span&gt;IPriceService&lt;/span&gt;&lt;/a&gt; implementations. The good news is that the &lt;a href=&quot;/link/80af4cbfd31242b2b7ea0c3430d76dd4.aspx?id=111919&quot;&gt;&lt;span&gt;default implementation&lt;/span&gt;&lt;/a&gt; actually supports pricing on products and it&amp;rsquo;s very easy to create your own pricing implementation! The former part means we can keep our implementation of the two interfaces to a minimum and rely on the default implementations as much as possible.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Ready for the bad news? The Catalog UI does not support prices directly on products; all operations (CRUD) will be on variants or packages. For editors, this means that any price change must be performed on a variant. Our provider then needs to intercept any price changes coming from the UI and make them into a product price change. How this is done will be explained briefly later in the post.&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;Product Level Pricing Provider&lt;/span&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;span&gt;Installation&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Installing the Product Level Pricing Provider (PLPP) is easy. The PLPP consists of 4 files. Two are the implementation of the &lt;/span&gt;&lt;span&gt;IPriceService&lt;/span&gt;&lt;span&gt; and &lt;/span&gt;&lt;span&gt;IPriceDetailService&lt;/span&gt;&lt;span&gt;. The project also comes with a &lt;/span&gt;&lt;span&gt;IConfigurableModule&lt;/span&gt;&lt;span&gt; class which will configure EPiServer to use our providers instead of the default ones. The last file contains helper extension methods that will help us find the product parent of a variant or translate the prices from a variant price to a product price. You install it by either adding the project to your EPiServer solution or you build the project and place the assembly in the bin directory.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Configuration&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;The PLPP adds one new configuration setting and that is if you want to store the prices on the variants or the products. I&amp;rsquo;ll explain the difference between the two values below.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;lt;appSettings&amp;gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;br /&gt; &lt;span&gt;...&amp;nbsp; &lt;/span&gt;&lt;br /&gt; &lt;span&gt;&amp;lt;add key=&quot;ProductLevelPricing&quot; value=&quot;true|false&quot; /&amp;gt;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br /&gt; &lt;span&gt;&amp;lt;appSettings&amp;gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If no &amp;ldquo;ProductLevelPricing&amp;rdquo; setting is found, the default pricing implementations will be used instead.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Store the product prices on the variants (ProductLevelPricing == false)&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;Storing the prices on the variants means that each variant for a product will have the same set of prices stored on all of them. If you have a product with two variants linked to it and three product prices, those three prices will be stored for each variant resulting in a total of six prices in the database. This works by assuming that all the variants start out with the same price (or no prices) and then synchronizing the variants when a price change is done to either of them. The read performance of this mode is the same as the default implementation as the price is still stored on the variants. The write performance however will take a toll as it needs to update the variant, get the new prices, find the sibling variants, delete the siblings&amp;rsquo; prices and update each sibling with the new prices. This is to ensure they are synchronized. As you can imagine, this will result in a performance hit and the hit will scale with the number of children/variants a parent product has. However, writing prices is generally an infrequent action so the performance hit will not matter on most sites.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Store the product prices on the product (ProductLevelPricing == true)&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;The other option is to store the prices on the product. If you have three prices on a product, then three prices will be stored in the database. This results in less redundant data but it also means a small incurred cost when fetching prices for a variant as we always need to find the product parent of the variant first. In your site you can avoid this cost by being sure only to query for product prices directly and by a sensible caching policy. This incurred cost cannot be avoided in the Catalog UI/Commerce Manager because the UI only deals with variant prices, but those are internal functions and the delay should be small.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Disclamer&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span&gt;This is only an example implementation and is offered as is. This is not a supported pricing provider by EPiServer and is not garanteed with upgrade/updates. If you find bugs or want to suggest improvements, feel free to contact me at the email below.&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;Limitations&lt;/span&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;A variant can only be linked to one product.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;The implementation assumes that all API calls are for one type of entry. It&amp;rsquo;s either variants or products never a mix of the two.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;For the API call &lt;/span&gt;&lt;span&gt;IList&amp;lt;IPriceDetailValue&amp;gt; Save(IEnumerable&amp;lt;IPriceDetailValue&amp;gt; priceValues)&lt;/span&gt;&lt;span&gt; priceValues is an array of prices that belongs to &lt;em&gt;one&lt;/em&gt; variant or product&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;This implementation was only tested on latest Commerce.Core and Commerce.UI Nuget package (8.11.1).&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;If product level pricing is not used (store prices on variants) and a price change is for a product, the price will not be saved on the product&amp;rsquo;s children and will be saved on the product.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Source&lt;/h3&gt;
&lt;p&gt;You can find the source on Expert Services Bitbucket account:&amp;nbsp;&lt;a href=&quot;https://bitbucket.org/episerver-es/product-level-pricing-provider/&quot;&gt;https://bitbucket.org/episerver-es/product-level-pricing-provider/&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span&gt;If you need to solve this problem, I hope this helps. Please feel free to contact me with any questions/suggestions/bugs in EPiServer Expert Services at Tobias.Nilsson@episerver.com.&lt;/span&gt;&lt;/em&gt;&lt;/p&gt;</id><updated>2015-04-17T01:41:05.4470000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Switching From Lucene to Solr</title><link href="https://world.optimizely.com/blogs/Tobias-Nilsson/Dates/2012/7/Switching-From-Lucene-to-Solr/" /><id>&lt;!-- body{     margin: 0 auto;     font-family: Georgia, Palatino, serif;     color: #444444;     line-height: 1;     max-width: 960px;     padding: 5px; } h1, h2, h3, h4 {     color: #111111;     font-weight: 400; } h1, h2, h3, h4, h5, p {     margin-bottom: 16px;     padding: 0; } h1 {     font-size: 28px; } h2 {     font-size: 22px;     margin: 20px 0 6px; } h3 {     font-size: 21px; } h4 {     font-size: 18px; } h5 {     font-size: 16px; } a {     color: #0099ff;     margin: 0;     padding: 0;     vertical-align: baseline; } a:hover {     text-decoration: none;     color: #ff6600; } a:visited {     color: purple; } ul, ol {     padding: 0;     margin: 0; } li {     line-height: 24px;     margin-left: 44px; } li ul, li ul {     margin-left: 24px; } p, ul, ol {     font-size: 14px;     line-height: 20px;     max-width: 540px; } pre {     padding: 0px 24px;     max-width: 800px;     white-space: pre-wrap; } code {     font-family: Consolas, Monaco, Andale Mono, monospace;     line-height: 1.5;     font-size: 13px; } aside {     display: block;     float: right;     width: 390px; } blockquote {     border-left:.5em solid #eee;     padding: 0 2em;     margin-left:0;     max-width: 476px; } blockquote  cite {     font-size:14px;     line-height:20px;     color:#bfbfbf; } blockquote cite:before {     content: &#39;\2014 \00A0&#39;; }  blockquote p {       color: #666;     max-width: 460px; } hr {     width: 540px;     text-align: left;     margin: 0 auto 0 0;     color: #999; }  button, input, select, textarea {   font-size: 100%;   margin: 0;   vertical-align: baseline;   *vertical-align: middle; } button, input {   line-height: normal;   *overflow: visible; } button::-moz-focus-inner, input::-moz-focus-inner {   border: 0;   padding: 0; } button, input[type=&quot;button&quot;], input[type=&quot;reset&quot;], input[type=&quot;submit&quot;] {   cursor: pointer;   -webkit-appearance: button; } input[type=checkbox], input[type=radio] {   cursor: pointer; } /* override default chrome &amp; firefox settings */ input:not([type=&quot;image&quot;]), textarea {   -webkit-box-sizing: content-box;   -moz-box-sizing: content-box;   box-sizing: content-box; }  input[type=&quot;search&quot;] {   -webkit-appearance: textfield;   -webkit-box-sizing: content-box;   -moz-box-sizing: content-box;   box-sizing: content-box; } input[type=&quot;search&quot;]::-webkit-search-decoration {   -webkit-appearance: none; } label, input, select, textarea {   font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;   font-size: 13px;   font-weight: normal;   line-height: normal;   margin-bottom: 18px; } input[type=checkbox], input[type=radio] {   cursor: pointer;   margin-bottom: 0; } input[type=text], input[type=password], textarea, select {   display: inline-block;   width: 210px;   padding: 4px;   font-size: 13px;   font-weight: normal;   line-height: 18px;   height: 18px;   color: #808080;   border: 1px solid #ccc;   -webkit-border-radius: 3px;   -moz-border-radius: 3px;   border-radius: 3px; } select, input[type=file] {   height: 27px;   line-height: 27px; } textarea {   height: auto; }  /* grey out placeholders */ :-moz-placeholder {   color: #bfbfbf; } ::-webkit-input-placeholder {   color: #bfbfbf; }  input[type=text], input[type=password], select, textarea {   -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;   -moz-transition: border linear 0.2s, box-shadow linear 0.2s;   transition: border linear 0.2s, box-shadow linear 0.2s;   -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);   -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);   box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1); } input[type=text]:focus, input[type=password]:focus, textarea:focus {   outline: none;   border-color: rgba(82, 168, 236, 0.8);   -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);   -moz-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);   box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6); }  /* buttons */ button {   display: inline-block;   padding: 4px 14px;   font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;   font-size: 13px;   line-height: 18px;   -webkit-border-radius: 4px;   -moz-border-radius: 4px;   border-radius: 4px;   -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);   -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);   box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);   background-color: #0064cd;   background-repeat: repeat-x;   background-image: -khtml-gradient(linear, left top, left bottom, from(#049cdb), to(#0064cd));   background-image: -moz-linear-gradient(top, #049cdb, #0064cd);   background-image: -ms-linear-gradient(top, #049cdb, #0064cd);   background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #049cdb), color-stop(100%, #0064cd));   background-image: -webkit-linear-gradient(top, #049cdb, #0064cd);   background-image: -o-linear-gradient(top, #049cdb, #0064cd);   background-image: linear-gradient(top, #049cdb, #0064cd);   color: #fff;   text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);   border: 1px solid #004b9a;   border-bottom-color: #003f81;   -webkit-transition: 0.1s linear all;   -moz-transition: 0.1s linear all;   transition: 0.1s linear all;   border-color: #0064cd #0064cd #003f81;   border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); } button:hover {   color: #fff;   background-position: 0 -15px;   text-decoration: none; } button:active {   -webkit-box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);   -moz-box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);   box-shadow: inset 0 3px 7px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); } button::-moz-focus-inner {   padding: 0;   border: 0; }  /* CSS stylesheet is based on Kevin Burke&#39;s Markdown.css project (http://kevinburke.bitbucket.org/markdowncss) */ --&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;In this blog I will talk about how easy (or hard) it is to switch from Lucene to Solr.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;EPiServer Commerce R2 SP2&lt;/em&gt; comes with three providers: Lucene (default), Solr and Solr 3.5.&lt;/p&gt;
&lt;p&gt;While the Lucene provider is .NET, Solr is based on Java and thus needs to be hosted on &lt;a title=&quot;Apache Tomcat &quot; href=&quot;http://tomcat.apache.org/&quot;&gt;Tomcat&lt;/a&gt; which is a HTTP Java web server.&lt;/p&gt;
&lt;p&gt;Because of this the requirements for Solr is a bit different than Lucene. First of you will need Java Runtime (JRE) installed, or the full JDK. After Java is installed Tomcat is next. You can download either version 7 or 6. The important part is that you choose to download the &lt;strong&gt;32-bit/64-bit Windows Service Installer&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;Extract the shipped Solr implementation to Tomcat. You can find it in the MediachaseECF folder in the web root of your CMS site.&lt;/p&gt;
&lt;p&gt;Open the zip file containing the solr implementation and copy the two folders in &lt;em&gt;\Tools\Search\SolrServer(350)&lt;/em&gt; to your Tomcat installation folder.&lt;/p&gt;
&lt;p&gt;After that you need to configure &lt;strong&gt;both&lt;/strong&gt; the CMS and Commerce Manager sites to use Solr by changing the &lt;strong&gt;Mediachase.Search.config&lt;/strong&gt; file. You can read how in the documentation linked below.&lt;/p&gt;
&lt;p&gt;You can find more thorough installation steps in the &lt;a href=&quot;http://sdk.episerver.com/commerce/1.1.2/Content/Developers%20Guide/ConfigurationDeployment/IN_ConfiguringSolrSearchPrvider.htm&quot;&gt;Commerce documentation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The steps outlined in the document works for the older Solr implementation as well, except the automatic generation of fields in the schema config you will have to configure the fields yourself.&lt;/p&gt;
&lt;p&gt;After you have followed the steps you should be able to build your index and do a search using it. You can verify that the index has been built and what it contains by visitng the admin mode of Solr which per default is located at &lt;em&gt;http://localhost:8080/solr/&lt;/em&gt;. One query you can try is &quot;&lt;em&gt;_content:a&lt;/em&gt;&quot; which translates to &quot;search the field _content for the string that begins with a&quot; (&lt;a href=&quot;http://khaidoan.wikidot.com/solr&quot;&gt;short query syntax guide&lt;/a&gt;). One thing to note is that only fields that are of the type &lt;strong&gt;text&lt;/strong&gt; can be searched this way. If you have a string field, it will not allow you to use wildcards. Also another thing that is good to know is that Solr doesn&#39;t support wildcards in the beginning of a search.&lt;/p&gt;
&lt;h2&gt;Default fields&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;_content&lt;/strong&gt; field we used above is special for two reasons. One because it is the default field, which means if you do a query without specifying the field it will search in the _content field:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;q=test =&amp;gt; _content:test&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;And two, because the default config copies a few fields into this field, makinging the field very rich in content.&lt;/p&gt;
&lt;p&gt;For example the default config can look like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;copyField source=&quot;name&quot; dest=&quot;_content&quot;/&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This tells Solr to copy whatever is in the &lt;strong&gt;name&lt;/strong&gt; field to the &lt;strong&gt;_content&lt;/strong&gt; field, adding to whatever information already was there.&lt;/p&gt;
&lt;p&gt;It is also important because the default Solr search provider implementation will not implicitly specify any fields for your search terms, so searching for &quot;candy&quot; on the front end site will lead to a &quot;q=candy&quot; query. Which equates to _content:candy thanks to _content being the default field.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt; &lt;em&gt;Tomcat logs every query, so if you want to see how your queries look when being send to Solr, look at the logs directory of you Tomcat installation folder.&lt;/em&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;As you see, getting the _content field right is important when it comes to what information you store and the index size. The larger index data you have, the longer the indexing will take. That leads me to the different options you have for index fields. The comment in &lt;strong&gt;catalog.schema.xml&lt;/strong&gt; does a pretty good job explaining it, but I will just do a quick recap of the most important fields below.&lt;/p&gt;
&lt;h2&gt;Configure index fields&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Name&lt;/strong&gt;: Mandatory the name for the field&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;type&lt;/strong&gt;: Mandatory the name of a previously defined type from the   section&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;indexed&lt;/strong&gt;: True if this field should be indexed (searchable or sortable)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;stored&lt;/strong&gt;: True if this field should be retrievable multiValued: true if this field may contain multiple values per document&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&#39;s take an example and see how it is defined:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;field name=&quot;_node&quot; type=&quot;string&quot; indexed=&quot;true&quot; stored=&quot;true&quot; multiValued=&quot;true&quot; /&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;_node&lt;/strong&gt; maps to what Catalog node the node/SKU is located. It&#39;s a string type which means we can&#39;t use wildcards or anything that differ from what is stored in the index (&lt;strong&gt;case sensitive!&lt;/strong&gt;). Finding SKU&#39;s located in the node &quot;DefaultNode&quot; means we need to search on the whole word and match the casing.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;q=_node:DefaultNode&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Further the field is indexed which means we can search and sort on it. It is also stored which means we can get the actual value from the index itself, and do not need to fetch the whole object from the database (DTO) to get the value. It is also multi valued which means it can have several values for one single entry. This makes sense as a entry can be in several nodes through linking.&lt;/p&gt;
&lt;p&gt;When you have all the index fields defined just as you like them and you feel comfortable with how long the indexing takes you are good (as again, more data means longer indexing)!&lt;/p&gt;
&lt;h2&gt;Bonus&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Unless you want to change the search provider that is...&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Right now we offer the source for the Solr 3.5 search provider as a download on &lt;a href=&quot;http://world.episerver.com&quot;&gt;EPiServer World&lt;/a&gt;. Download and compilate it and you have more freedom on how the final query will look when it is sent to Solr. This greater control can make the search results more to your and your customer&#39;s liking. After all, many customers have specific needs when it comes to search and a prebuilt one-size-fits-all solution will hinder that.&lt;/p&gt;
&lt;p&gt;One of the method you want to take a look at is BuildQuery in SolrSearchQueryBuilder.cs where the actual query is built.&lt;/p&gt;
&lt;h2&gt;The End&lt;/h2&gt;
&lt;p&gt;As you can see switching from Lucene to Solr is quite easy, it&#39;s the customization part that can be hard.&lt;/p&gt;
&lt;!-- This document was created with MarkdownPad, the Markdown editor for Windows (http://markdownpad.com) --&gt;</id><updated>2012-07-09T14:33:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Problems installing EPiServer Commerce</title><link href="https://world.optimizely.com/blogs/Tobias-Nilsson/Dates/2012/1/Problems-installing-EPiServer-Commerce/" /><id>&lt;h2&gt;Are you having troubles installing Commerce?&amp;nbsp;&lt;/h2&gt;
&lt;p&gt;Are you receiving this error message:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;System.Management.Automation.PSInvalidOperationException: The WriteObject and WriteError methods cannot be called from outside the overrides of the BeginProcessing, ProcessRecord, and EndProcessing methods, and only from that same thread. Validate that the cmdlet makes these calls correctly, or please contact Microsoft Support Services.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately the installation should copy the log files to the application root, but it doesn&#39;t seems to do that. To see the actual error and not just a generic Powershell error, we need to modify the installation script a bit (find this in the Commerce installation directory).&lt;/p&gt;
&lt;p&gt;First comment out the line that deletes the temp folder:&lt;/p&gt;
&lt;p&gt;# DeleteFolder $unzipTempFolder&lt;/p&gt;
&lt;p&gt;Then remove the signature at the bottom of the file as it&#39;s invalid now and then save the file.&lt;/p&gt;
&lt;p&gt;# SIG # Begin signature block&lt;br /&gt;# MIIVNwYJKoZIhvcNAQcCoIIVKDCCFSQCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB&lt;br /&gt;# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR&lt;br /&gt;..... lots of text....&lt;br /&gt;# ISmDxA7ThKuIxlg=&lt;br /&gt;# SIG # End signature block&lt;/p&gt;
&lt;p&gt;As the file is no longer signed, we can&#39;t run it before we have made some PowerShell policy adjustments. The default policy is to not allow unsigned scripts to run. So we must change it&lt;/p&gt;
&lt;p&gt;PS C:\Users\tobias&amp;gt; Set-ExecutionPolicy &#39;unrestricted&#39;&lt;/p&gt;
&lt;p&gt;Now run EPiServer deployment center and run the Commerce installation and after it have failed you should have a new catalog in your c: drive. In that folder you should find a log folder which contains the installation logs (installer logs). There you will find what the error really was.&lt;/p&gt;
&lt;p&gt;Hope this helps with your Commerce install issues!&lt;/p&gt;</id><updated>2012-01-23T11:07:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Mapping a folder with non ascii characters with EPiServer&#39;s VPPs</title><link href="https://world.optimizely.com/blogs/Tobias-Nilsson/Dates/2011/9/Mapping-a-folder-with-non-ascii-characters-with-EPiServers-VPPs/" /><id>&lt;p&gt;Just a quick tips to you out there that aren&#39;t english or for some odd reason have folders that have non ascii characters in physical folder names, i.e. &quot;c:\files\F&#246;lder&quot;. You might have tried to mapp it to a VPP before and got a error about non compatible characters in your episerver.config. It may look something like this:&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;System.TypeInitializationException: Ett undantagsfel uppstod f&#246;r typinitieraren f&#246;r EPiServer.DataFactory. ---&amp;gt; System.Configuration.ConfigurationErrorsException: Det finns ett ogiltigt tecken i den givna kodningen. Rad 19, position 180. (C:\EPiServer\Sites\World\episerver.config line 19) ---&amp;gt; System.Xml.XmlException: Det finns ett ogiltigt tecken i den givna kodningen. Rad 19, position 180.&lt;br /&gt; vid System.Xml.XmlTextReaderImpl.Throw(Exception e)&lt;br /&gt; vid System.Xml.XmlTextReaderImpl.Throw(String res, String arg)&lt;br /&gt; vid System.Xml.XmlTextReaderImpl.Throw(Int32 pos, String res)&lt;br /&gt; vid System.Xml.XmlTextReaderImpl.InvalidCharRecovery(Int32&amp;amp; bytesCount, Int32&amp;amp; charsCount)&lt;br /&gt; vid System.Xml.XmlTextReaderImpl.GetChars(Int32 maxCharsCount)&lt;br /&gt; vid System.Xml.XmlTextReaderImpl.ReadData()&lt;br /&gt; vid System.Xml.XmlTextReaderImpl.ParseAttributeValueSlow(Int32 curPos, Char quoteChar, NodeData attr)&lt;br /&gt; vid System.Xml.XmlTextReaderImpl.ParseAttributes()&lt;br /&gt; vid System.Xml.XmlTextReaderImpl.ParseElement()&lt;br /&gt; vid System.Xml.XmlTextReaderImpl.ParseElementContent()&lt;br /&gt; vid System.Xml.XmlTextReaderImpl.Read()&lt;br /&gt; vid System.Xml.XmlTextReader.Read()&lt;br /&gt; vid System.Configuration.XmlUtil.CopyXmlNode(XmlUtilWriter utilWriter)&lt;br /&gt; vid System.Configuration.XmlUtil.CopyElement(XmlUtilWriter utilWriter)&lt;br /&gt; vid System.Configuration.XmlUtil.CopySection()&lt;br /&gt; vid System.Configuration.BaseConfigurationRecord.LoadConfigSource(String name, SectionXmlInfo sectionXmlInfo)&lt;br /&gt; vid System.Configuration.BaseConfigurationRecord.GetSectionXmlReader(String[] keys, SectionInput input)&lt;br /&gt; --- Slut p&#229; stacksp&#229;rning f&#246;r interna undantag ---&lt;br /&gt; vid System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)&lt;br /&gt; vid System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object&amp;amp; result, Object&amp;amp; resultRuntimeObject)&lt;br /&gt; vid System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object&amp;amp; result, Object&amp;amp; resultRuntimeObject)&lt;br /&gt; vid System.Configuration.BaseConfigurationRecord.GetSection(String configKey, Boolean getLkg, Boolean checkPermission)&lt;br /&gt; vid System.Configuration.Configuration.GetSection(String sectionName)&lt;br /&gt; vid EPiServer.Configuration.EPiServerSection.get_Instance()&lt;br /&gt;&amp;nbsp;vid EPiServer.DataFactory..cctor()&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;To get around this problem can encode your path so it reads c:\files\F&#195;&#182;lder and put that as your physicalPath in the VPP configuration (episerver.config). I used&amp;nbsp;http://coderstoolbox.net/string/ for this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OR&lt;/strong&gt; like Peter Suneson &lt;a href=&quot;/link/350bb1ff13c241b0a29dd21f6a53037a.aspx?epslanguage=en&quot;&gt;figured out&lt;/a&gt; just resave the episerver.config as utf-8.&lt;/p&gt;</id><updated>2011-09-22T22:27:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>A restore page plugin</title><link href="https://world.optimizely.com/blogs/Tobias-Nilsson/Dates/2011/8/A-restore-page-plugin/" /><id>&lt;p&gt;&lt;em&gt;Hi everyone!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;I recently created a plugin that borrows it&#39;s functionality from the Windows wastebasket. In Windows you can restore a file you have deleted, i.e. moved to the wastebasket. I wanted to replicate this behavior for EPiServer CMS. And with further ado:&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Retore Page Plugin&lt;/h2&gt;
&lt;p&gt;Like I said it will give you the possibility to restore the page back to its previous owner (parent). So let&#39;s say that you deleted a page and now you want it back in the site tree, but you can&#39;t remember under which root is was located.Page restore to the &lt;strong&gt;rescue&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/cd141956cd1c48d39261ab468cd057a1.png&quot; alt=&quot;&quot; width=&quot;308&quot; height=&quot;239&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Now you can right click the page and select &quot;Restore&quot;, it wil then bring you to a confirmation page where you can see where in the site tree it will be relocated before actually doing anything. And that&#39;s about it!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/240eebcbe6b6424fb366166b1a1afd19.png&quot; alt=&quot;&quot; width=&quot;867&quot; height=&quot;383&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This is in &lt;strong&gt;no way tested&lt;/strong&gt; or tried thoroughly. I was hoping you guys could be my lab monkies and test it out ;).&lt;/p&gt;
&lt;p&gt;But if you do find anything strange, report it to me and I&#39;ll see if I can be bothered to do anything about it.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/13ed1a97530646c8ab5035e695c75024.zip&quot;&gt;DOWNLOAD&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The package has been updated as I forgot to include the part of the code that was responsible for setting up the menu button, but also the part which added and deleted restore points when you moved pages. Sorry for that ;)&lt;/strong&gt;&lt;/p&gt;</id><updated>2011-08-03T22:55:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Initialize Community 4.0 without IIS</title><link href="https://world.optimizely.com/blogs/Tobias-Nilsson/Dates/2011/1/Initialize-Community-40-without-IIS/" /><id>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Sometimes you want to initialize EPiServer Community without involving the IIS.&amp;nbsp; For example when you decide not to use IIS for servicing your web pages or when you want to do unit testing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Command line program&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&#39;ve therefore created a little command line program that does this. It initializes Community (and also search) and fetches the first blog post made (ID = 1). You can then use this code as a base for doing your own programs that need access to the Community API.&lt;/p&gt;
&lt;p&gt;To use it just compile it and place it amongs a web.config (for a community site) and a connectionstrings.config along with every dll the web.config wants plus the dll&#39;s the project needs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Download&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href=&quot;/link/5c85862697374e53b06699ab9ae718be.zip&quot;&gt;InitializeCommunityCommandLine&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/link/3c672b8fe89c4c5cae0e355760d201b9.jpg&quot; alt=&quot;&quot; width=&quot;303&quot; height=&quot;540&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Thanks to Kristoffer @ dev for giving me the inspiration and the file this program was heavily based on!&lt;/p&gt;</id><updated>2011-01-21T15:17:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Troubleshooting the Scheduler</title><link href="https://world.optimizely.com/blogs/Tobias-Nilsson/Dates/2010/12/Troubleshooting-the-Scheduler/" /><id>&lt;p class=&quot;introduction&quot;&gt;&amp;nbsp;We have seen a influx of cases regarding the Scheduler  service, so I thought it would be a good time to write about how to troubleshoot  it yourself!&lt;/p&gt;
&lt;h1&gt;The deal&lt;/h1&gt;
&lt;p&gt;The scheduling service run jobs you define for it and also EPiServer&#39;s  own shipped jobs, such as archiving pages, subscription and delete wastebasket  pages.&lt;/p&gt;
&lt;p&gt;But sometimes it goes wrong and the scheduler&amp;nbsp;doesn&#39;t automatically run the  jobs anymore. It&#39;s stuck.&lt;/p&gt;
&lt;h1&gt;The tactics&lt;/h1&gt;
&lt;p&gt;We have a few tactics we&amp;nbsp;use. First one is to delete the, possibly corrupted,  &amp;nbsp;config file and there&#39;s a &lt;a href=&quot;http://world.episerver.com/FAQ/Items/Scheduler-does-not-run-scheduled-jobs-automatically/&quot;&gt;FAQ  item&lt;/a&gt; describing how to do that.&amp;nbsp;If that doesn&#39;t work we usually suggest to  the client to delete all the rows in the two tables the scheduler uses,  tblScheduledItem and tblScheduledItemLog. To be able to do that you must first  deactivate the foreign key defined on tblScheduledItemLog to tblScheduledItem.  This can be achieved using the first line below.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: xx-small;&quot;&gt;ALTER TABLE tblScheduledItemLog NOCHECK CONSTRAINT  ALL&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-size: xx-small;&quot;&gt;ALTER TABLE tblScheduledItemLog CHECK CONSTRAINT  ALL&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Don&#39;t worry about truncating these two tables as they are recreated by the  Scheduler service. But as always when making changes directly in the database  you should take a backup. Safety first, don&#39;t forget that!&lt;/p&gt;
&lt;p&gt;The third way is to figure it out yourself by logging the Scheduler service.  The scheduler service can use the log4net logging framework (as all of our services), so you only need to  drop a log4net.dll and a &lt;a href=&quot;http://logging.apache.org/log4net/release/config-examples.html&quot;&gt;log4net.config&lt;/a&gt;&amp;nbsp;(see  the fileAppender section)&amp;nbsp;in its folder for it to start logging. This way you  can see what&#39;s causing the scheduler to fail and hopefully you can fix it  yourself.&lt;/p&gt;
&lt;h3&gt;Example of a log4net.config file&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&amp;gt;&lt;br /&gt;&amp;lt;log4net&amp;gt;&lt;br /&gt; &amp;lt;appender name=&quot;ErrorAppender&quot; type=&quot;log4net.Appender.FileAppender&quot; &amp;gt;&lt;br /&gt; &amp;lt;file value=&quot;C:\temp\LogServerError.log&quot; /&amp;gt;&lt;br /&gt; &amp;lt;appendToFile value=&quot;true&quot; /&amp;gt;&lt;br /&gt; &amp;lt;layout type=&quot;log4net.Layout.PatternLayout&quot;&amp;gt;&lt;br /&gt; &amp;lt;conversionPattern value=&quot;%d [%t] %l - %m%n&quot; /&amp;gt;&lt;br /&gt; &amp;lt;/layout&amp;gt;&lt;br /&gt; &amp;lt;/appender&amp;gt;&lt;br /&gt; &lt;br /&gt; &amp;lt;root&amp;gt;&lt;br /&gt; &amp;lt;level value=&quot;ALL&quot; /&amp;gt;&lt;br /&gt; &amp;lt;appender-ref ref=&quot;ErrorAppender&quot; /&amp;gt;&lt;br /&gt; &amp;lt;/root&amp;gt;&lt;br /&gt;&amp;lt;/log4net&amp;gt;&lt;/p&gt;</id><updated>2010-12-20T08:43:00.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>XForm reserved names for input fields</title><link href="https://world.optimizely.com/blogs/Tobias-Nilsson/Dates/2010/11/XForm-reserved-names-for-input-fields/" /><id>&lt;p&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;There&#39;s a bug in the XForm implementation that  &quot;allow&quot; users to add a input field with the name &quot;id&quot;. I put allow in quotes  because in CMS 6, the XForm edit dialog will crash and not let you save the  XForm. But in CMS 5+ it actually lets you save it and it will later&amp;nbsp;crash when  you&#39;re trying to get the form data out. &lt;strong&gt;Mohahaha-haha&lt;/strong&gt;... This  is especially evil when migrating over from CMS 4, as there was no problem  having a field called id there, so you could have a whole bunch of these just  waiting to explode after you migrated. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;This behavior is because id is a reserved  keyword for XForms. So it&#39;s important to tell this to your  editors.&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;And it doesn&#39;t stop there. if you import a form  from CMS 4 into CMS 6 and get this error,&amp;nbsp;the normal thing would be to delete it  and start anew, but oh&amp;nbsp;no. That would be to easy right? Because you can&#39;t delete  it in XForm editor. Actually you can&#39;t do anything&amp;nbsp;because&amp;nbsp;it will crash as soon  as it tries to read the XForm&#39;s xml definition. &lt;/span&gt;&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;Database to the  rescue!&lt;/span&gt;&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;By now you might have started to sweat. But take  it easy, you can remove it, but you will have to do it directly&amp;nbsp;in the database.  First thing you want to do is to find the offending XForm in the  tblSystemBigTable (or the more convenient way of using a view: dbo.VW_XForms).  The column&amp;nbsp;FormName&amp;nbsp;hold the XForm&#39;s name so you can locate it that way (or  using &lt;/span&gt;&lt;a href=&quot;http://world.episerver.com/Support/Support-Tools/&quot;&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;Windmill Explorer&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;). The  row also contain the GUID for the XForm. Use this GUID to remove the XForm from  the tables it is referenced in by using it as the input for the stored procedure  &lt;strong&gt;dbo.BigTableDeleteItem. &lt;/strong&gt;This should take care of it and you  should not see it in the XForm browser anymore or in a property.&lt;/span&gt;&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;CMS 5 R2 SP2&lt;/span&gt;&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;&quot;What about me&quot; you say? Well for you it&#39;s  easier or harder depending on what you want to do.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;If you want to delete the XForm and go on with  your life, than it&#39;s easier, as you can do it as you normally would via the  XForm editor. But if you want to extract the data, it&#39;s harder.&lt;/span&gt;&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;&quot;Uh yeah that&#39;s great, but what about  all the data. Can we get that back?!&quot;&lt;/span&gt;&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;Yes! In &lt;em&gt;CMS 6&lt;/em&gt; it&#39;s a bit easier because  the data isn&#39;t serialized, i.e it is in plain text. And every XForm  automatically gets its own database view that will show you the submitted data,  so use those. If you don&#39;t want to use the database you can always write  something that takes the values and writes them to a csv file or something  similar. And this is exactly what I&#39;ve done, but for the CMS 5 R2 SP2&amp;nbsp;version.  This because&amp;nbsp;the CMS 5 versions doesn&#39;t have any views and the data is  serialized, so it&#39;s much harder to extract it directly via a SQL  script.&lt;/span&gt;&lt;/p&gt;
&lt;h5&gt;&lt;strong&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;The &quot;tool&quot;&lt;/span&gt;&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;This tool is for &lt;em&gt;CMS 5 R2 SP2&lt;/em&gt;&amp;nbsp;and it&#39;s  not tested at all (well it runs!). The idea is to give you the basic code  skeleton and you can then modify it to your needs. So if you are going to use&amp;nbsp;it  you should first go through and understand the code and then do the necessary  changes. But hopefully it is easy to understand and if you do some improvements  you are welcome&amp;nbsp;to post them here for others to enjoy (pleaase do some  refactoring, pretty pleeeaase ;). &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/c8cc177e733448f0964b675a1b14a4fd.zip&quot;&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;XFormExport.zip&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;Installation: Include the files to your project  and compile.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;Instructions: Input the XForm&#39;s GUID (use &lt;/span&gt;&lt;a href=&quot;http://world.episerver.com/Support/Support-Tools/&quot;&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;Windmill explorer&lt;/span&gt;&lt;/a&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;&amp;nbsp;to  find it) for which you want to export the form data from. The tool then goes  through all the form data postings and writes them to a file in c:\temp\xform,  so make sure the IIS account has write/read access to it.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: small;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;The error you receive when trying to save the XForm or export data from it:&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: &amp;amp;amp;amp; font-size: x-small;&quot;&gt;Property Id must be of type System.Guid or EPiServer.Data.Identity&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;</id><updated>2010-11-02T09:31:00.0000000Z</updated><summary type="html">Blog post</summary></entry></feed>