<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><description>Code and samples for working in Sitecore</description><title>InSitecore</title><generator>Tumblr (3.0; @insitecore)</generator><link>https://insitecore.tumblr.com/</link><item><title>Sitecore Language Name Validator</title><description>&lt;p&gt;In our discussion of &lt;code&gt;LanguageResolver&lt;/code&gt;, one of the issues we identified was the possibility of Item Name and Language Name collisions. That is, Sitecore will interpret the first slug of a URL as a language if it can &amp;ndash; even if that language isn&amp;rsquo;t in use on the Site or in the Instance.&lt;/p&gt;

&lt;p&gt;This is a problem for abbreviations that collide with languages. Some common abbreviations that might cause conflict include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AR (Arkansas) maps to Arabic&lt;/li&gt;
&lt;li&gt;CA (Canada) maps to Catalan&lt;/li&gt;
&lt;li&gt;ID (Identity) maps to Indonesian&lt;/li&gt;
&lt;li&gt;IS (Information Services) maps to Icelandic&lt;/li&gt;
&lt;li&gt;IT (Information Technology) maps to the Italian language (this is the example that brought this issue to my attention)&lt;/li&gt;
&lt;li&gt;Etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One possible solution to this problem is to add a custom validator to Sitecore that reports a validation error whenever a top-level item has a name conflict with a language. The user is then free to change the name to prevent a language conflict.&lt;/p&gt;

&lt;h2&gt;Custom Validators&lt;/h2&gt;

&lt;p&gt;Before we write our code, let&amp;rsquo;s review custom validation. Validators allows you to indicate warnings and errors about the fields of items. Validation comes in three forms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Field Validators. Field validators are assigned on field definition items and run against the value of the target field.&lt;/li&gt;
&lt;li&gt;Item Validators. Item-level validation can be assigned on Template Standard Values and will run against all items that implement from the template (or one of its inheritors).&lt;/li&gt;
&lt;li&gt;Global Item Validators. These are Item-level validation items, but they run against all items, all of the time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are the steps for creating a custom validator:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a class that inherits from &lt;code&gt;Sitecore.Data.Validators.StandardValidator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Implement the required methods:
  &lt;ol&gt;
    &lt;li&gt;Parameterless constructor&lt;/li&gt;
    &lt;li&gt;Serialization constructor&lt;/li&gt;
    &lt;li&gt;Name property&lt;/li&gt;
    &lt;li&gt;Evaluate method&lt;/li&gt;
    &lt;li&gt;GetMaxValidateResult method&lt;/li&gt;
  &lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;Compile and add your assembly to your Sitecore Instance&amp;rsquo;s `bin` directory&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;Validation Rule&lt;/code&gt; definition item in the Content Tree under &lt;code&gt;/sitecore/system/Settings/Validation Rules&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Apply the rule using a validation rule field
  &lt;ol&gt;
    &lt;li&gt;For Field Validators, apply the rule on a field definition item&lt;/li&gt;
    &lt;li&gt;For Item Validators, apply the rule on a Template Standard Values item&lt;/li&gt;
    &lt;li&gt;For Global Item Validators, apply  the rule on the &lt;code&gt;/sitecore/system/Settings/Validation Rules/Global Rules&lt;/code&gt; item&lt;/li&gt;
  &lt;/ol&gt;
&lt;/li&gt;&lt;/ol&gt;

&lt;p&gt;If you&amp;rsquo;re using Sitecore Rocks, instead of creating a class in Step 1, create a Validation item in the Sitecore &amp;gt; UI group of the Add New Item dialog. This will create the class, and a definition item in the Content Tree of the master database.&lt;/p&gt;

&lt;h2&gt;Implementation&lt;/h2&gt;

&lt;p&gt;This brings us to the implementation for our case. Our validator needs to check that an item won&amp;rsquo;t create a name conflict. We&amp;rsquo;ll be checking for these scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An item is an immediate child of a site&amp;rsquo;s Home item and the item&amp;rsquo;s Name or Display Name can be parsed as a language&lt;/li&gt;
&lt;li&gt;When the item&amp;rsquo;s link is generated, the first slug in the URL can be parsed as a language&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We&amp;rsquo;ll need to check every Site defined in the instance, so we can correctly handle multi-site configurations. However, many Sites don&amp;rsquo;t need validating (e.g., the &lt;code&gt;shell&lt;/code&gt; Site for the Sitecore UI). Validation items have a &lt;code&gt;Parameters&lt;/code&gt; field. We can use this field to send in runtime configuration to our validation. In our case, we&amp;rsquo;ll let users specify a Sites parameter in this field, e.g., &lt;code&gt;Sites=website&lt;/code&gt; to check just the &lt;code&gt;website&lt;/code&gt; Site.&lt;/p&gt;

&lt;p&gt;So here&amp;rsquo;s the sample code. Note that the first several lines are mostly boilerplate from Rocks. The meat of this implementation is in the Evaluate method.&lt;/p&gt;

&lt;pre class="prettyprint linenums lang-cs"&gt;
namespace InSitecore.Sample.Validation {
    using System;
    using System.Collections.Generic;
    using System.Runtime.Serialization;
    using Sitecore;
    using Sitecore.Data.Validators;
    using Sitecore.Globalization;
    using Sitecore.Links;
    using Sitecore.Sites;
    using Sitecore.Web;

    // TODO: Automatically created Item in Master database
    // "/sitecore/system/Settings/Validation Rules/
    // Item Rules/LanguageNameConflictValidator" when creating
    // LanguageNameConflictValidator class. 

    [Serializable]
    public class LanguageNameConflictValidator : StandardValidator {
        public LanguageNameConflictValidator() {
        }

        public LanguageNameConflictValidator(
            SerializationInfo info, StreamingContext context )
            : base( info, context ) {
        }

        public override string Name {
            get {
                return "Language Name Conflict Validator";
            }
        }

        protected override ValidatorResult Evaluate() {
            var item = this.GetItem();

            // Starting assumptions: we have an item, it's a content item
            // (e.g., from /sitecore/content), and it has a parent.
            // Return if these assumptions aren't met
            if( item == null
                    || item.Parent == null
                    || !item.Paths.IsContentItem ) {
                return ValidatorResult.Valid;
            }

            // Get a list of sites to check.
            // If no sites are specified, load them all
            var siteNames = new List();
            if( this.Parameters.ContainsKey( "sites" ) ) {
                siteNames.AddRange(
                    this.Parameters[ "sites" ].Split( new[] { ',', '|' } )
                );
            }

            if( siteNames.Count == 0 ) {
                siteNames.AddRange(
                    Sitecore.Configuration.Factory.GetSiteNames()
                );
            }

            // Loop the sites, checking if this is a child of that site
            foreach( var siteName in siteNames ) {
                var site = Sitecore.Configuration.Factory.GetSite( siteName );

                if( site == null ) { continue; }

                var siteRootItem = Context.Database.GetItem( site.StartPath );
                if( siteRootItem == null ) { continue; }

                // We only need to consider the case when an item is an immediate
                // child of a home item
                // NB: This might not be a good assumption for a specific
                // implementation; for example,
                // if you're using your own LinkProvider
                if( item.Parent.ID != siteRootItem.ID ) { continue; }

                // Now, try a number of different ways
                // of testing if there is a language
                // confict with this item
                var triggerName = "";
                Language lang = null;

                if( Language.TryParse( item.Name, out lang ) ) {
                    triggerName = "Name";

                } else if( Language.TryParse( item.DisplayName, out lang ) ) {
                    triggerName = "Display Name";

                } else {
                    // If the Name and DisplayName didn't match,
                    // maybe the generated URL will.
                    // We're going to use a SiteContextSwitcher to
                    // temporarily get Sitecore
                    // to act like Context.Site is pointing to a
                    // different site. This lets
                    // us use the settings for that other site.
                    string url = null;
                    using( new SiteContextSwitcher( site ) ) {
                        // Make sure that we're not going to see an actual langague slug in the URL
                        var options = new UrlOptions() {
                            LanguageEmbedding = LanguageEmbedding.Never
                        };
                        url = LinkManager.GetItemUrl( item, options );
                    }
                    // This will get the URL's file path
                    // Basically, the non-domain, non-query string
                    // portion of the URL
                    var filePath = WebUtil.ExtractFilePath( url ?? "" );
                    var languageSlug = WebUtil.ExtractLanguageName(
                        filePath ?? ""
                    );

                    if( Language.TryParse( languageSlug, out lang ) ) {
                        triggerName = "URL's file path (" + filePath ?? "" + ")";
                    }
                }

                if( lang != null ) {
                    // We matched a language; set the validation error
                    this.Text = this.GetText(
                        "The item \"{0}\" is a top-level child of "
                        + the \"{1}\" site and its {2} "
                        + "has a conflict with the {3} language.",
                        item.Name, site.Name, triggerName,
                        lang.CultureInfo.DisplayName
                        );
                    return this.GetFailedResult( ValidatorResult.Error );
                }
            }
            return ValidatorResult.Valid;
        }

        protected override ValidatorResult GetMaxValidatorResult() {
            return this.GetFailedResult( ValidatorResult.Error );
        }
    }
}
&lt;/pre&gt;</description><link>https://insitecore.tumblr.com/post/42350951454</link><guid>https://insitecore.tumblr.com/post/42350951454</guid><pubDate>Tue, 05 Feb 2013 08:12:25 -0500</pubDate><category>Sitecore</category><category>Pipelines</category></item><item><title>Thoughts on httpRequestBegin - Custom Language Resolver</title><description>&lt;p&gt;Last week we took a look at the &lt;a href="http://insitecore.tumblr.com/post/37734162227/sitecore-httprequestbegin-pipeline-in-detail" title="httpRequestBegin Pipeline"&gt;&lt;code&gt;httpRequestBegin&lt;/code&gt;&lt;/a&gt; pipeline and overriding the &lt;a href="http://insitecore.tumblr.com/post/37848690556/thoughts-on-httprequestbegin-custom-item-lookups" title="httpRequestBegin Pipeline - Custom Item Resolver"&gt;&lt;code&gt;ItemResolver&lt;/code&gt;&lt;/a&gt;. Today, let&amp;rsquo;s give some time to the &lt;code&gt;LanguageResolver&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;Overriding Options&lt;/h2&gt;

&lt;p&gt;Just as in the &lt;code&gt;ItemResolver&lt;/code&gt; case, there are two basic ways to override &lt;code&gt;LanguageResolver&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Inherit and extend the existing &lt;code&gt;LanguageResolver&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create a new processor that acts in addition to the standard &lt;code&gt;LanguageResolver&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;However, with Languages specifically, you might want to take a third option: replacing the standard &lt;code&gt;LanguageResolver&lt;/code&gt; completely.&lt;/p&gt;

&lt;h2&gt;&lt;a id="TheProblemwithLanguage"&gt;The Problem with Language&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Unlike some other processors, the &lt;code&gt;LanguageResolver&lt;/code&gt; &lt;strong&gt;does not&lt;/strong&gt; skip processing if language has already been specified earlier in the pipeline. So, even if you create a new processor that happens before &lt;code&gt;LanguageResolver&lt;/code&gt;, if Sitecore picks up a language setting in &lt;code&gt;LanguageResolver&lt;/code&gt;, your settings will be discarded.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;Sitecore&amp;rsquo;s standard &lt;code&gt;LanguageResolver&lt;/code&gt; will look for languages in two different ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;code&gt;sc_lang&lt;/code&gt; query string parameter. E.g., &lt;code&gt;&lt;a href="http://site.net/page.aspx?sc_lang=en"&gt;http://site.net/page.aspx?sc_lang=en&lt;/a&gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;A language code embedded as the first slug in a URL. E.g., in &lt;code&gt;&lt;a href="http://site.net/en/page.aspx"&gt;http://site.net/en/page.aspx&lt;/a&gt;&lt;/code&gt; the &lt;code&gt;/en/&lt;/code&gt; chunk will be interpreted as requesting the English language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(You can read the details &lt;a href="http://insitecore.tumblr.com/post/37734162227/sitecore-httprequestbegin-pipeline-in-detail#LanguageResolver" title="LanguageResolver Details"&gt;here&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;This poses a special problem if your URLs include an initial slug that looks like a language. For example, one client told me that they tried to have an IT department top-level section on their website, which would generate links like &lt;a href="http://site.net/IT/some-page.aspx."&gt;http://site.net/IT/some-page.aspx.&lt;/a&gt; The &lt;code&gt;LanguageResolver&lt;/code&gt; would find the initial &lt;code&gt;/IT/&lt;/code&gt; slug and interpret it as a language. Instead of trying to find an item at &lt;code&gt;/sitecore/content/home/IT/some-page&lt;/code&gt; with an English language version, it would try to find an item at &lt;code&gt;/sitecore/content/home/some-page&lt;/code&gt; with an Italian language version. Clearly, not the desired result.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sitecore will try to interpret any initial slug as a language even if that language is not in use on the site or the Sitecore instance.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;&lt;a id="LinkManagerandlanguageEmbedding"&gt;LinkManager and &lt;code&gt;languageEmbedding&lt;/code&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Sitecore remembers your language selection by saving a cookie with the name &lt;code&gt;&amp;lt;SiteName&amp;gt;#lang&lt;/code&gt;. If you have cookies turned off, Sitecore can&amp;rsquo;t remember your language selection across requests.&lt;/p&gt;

&lt;p&gt;To get around this problem, you can use the &lt;code&gt;languageEmbedding&lt;/code&gt; attribute on the &lt;code&gt;LinkProvider&lt;/code&gt; in &lt;code&gt;web.config&lt;/code&gt;. That attribute can take three values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;always&lt;/code&gt;: Always embed the language in the link. Whenever a link is requested from the &lt;code&gt;LinkProvider&lt;/code&gt;, Sitecore will embed the item&amp;rsquo;s language in the URL as an initial slug, so it can be found by &lt;code&gt;LanguageResolver&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;never&lt;/code&gt;: Never embed the language in the link.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;asNeeded&lt;/code&gt;: Embed the language in the link &lt;em&gt;only until language has been set&lt;/em&gt;. &lt;strong&gt;The &lt;code&gt;asNeeded&lt;/code&gt; value should be avoided&lt;/strong&gt; because URLs for the same item will change during a single visit to the site. That&amp;rsquo;s bad for SEO and bad for predictable  URLs in general.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using &lt;code&gt;languageEmbedding&lt;/code&gt; nicely gets around the cookie issue, but it also has the nice effect of separating your URLs for different languages.&lt;/p&gt;

&lt;h2&gt;&lt;a id="ChallengesandSolutions"&gt;Challenges &amp;amp; Solutions&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;We&amp;rsquo;re left with a number of challenges, and some potential solutions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you want to handle languages yourself, even if you create an earlier language processor, Sitecore will disregard the language selection you make if it &lt;code&gt;LanguageResolver&lt;/code&gt; detects a language setting. To resolve this, you could add your custom processor &lt;em&gt;after&lt;/em&gt; the standard &lt;code&gt;LanguageProcessor&lt;/code&gt;. However, you&amp;rsquo;ll have to manually check that Sitecore hasn&amp;rsquo;t set its language in a way you want to handle so you can roll back to the default language for the site.&lt;/li&gt;
&lt;li&gt;You might have name collisions with top-level site sections and language codes. You could create item-level validation that does not allow top-level items to use names or display names that collide with languages. To test this, you could use the &lt;code&gt;Sitecore.Globalization.Language.TryParse&lt;/code&gt; static method. (Stay tuned, my next post will have a demo implementation for this approach.)&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To persist language choices across requests, Sitecore only has two options: URL embedding and cookies. However, there are many approaches that might be useful. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DMS Tag value on the visitor reporting their preferred language&lt;/li&gt;
&lt;li&gt;User profile setting for the visitor&amp;rsquo;s preferred language&lt;/li&gt;
&lt;li&gt;ASP.NET Session variables that can be retrieved using cookie-less sessions&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The current implementation of detecting language requests only has two approaches: &lt;code&gt;sc_lang&lt;/code&gt; query strings and URL-embedded language codes, but you may be interested in using other techniques. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The culture reported by the browser&lt;/li&gt;
&lt;li&gt;Most common language used in the region detected with a geo-ip lookup&lt;/li&gt;
&lt;li&gt;The language indicated by the display name of the item (i.e., enhancing the &lt;code&gt;ItemResolver&lt;/code&gt; to look items up by their display name in any language, then specifying the language based on the language version found).&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;a name="SolvingLanguagetheSitecoreWay"&gt;Solving Language the Sitecore Way&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;Each of these individual problems can be addressed independently, based on your specific implementation requirements. And, if you have a monolingual website, none of this really matters.&lt;/p&gt;

&lt;p&gt;But, if you approach the problem by creating a single new custom &lt;code&gt;LanguageResolver&lt;/code&gt; that tries to deal with all of the issues identified in this post, you&amp;rsquo;ll end up with a big class full of implementation details. Sitecore has a pattern that we like to use in cases like this: Pipelines!&lt;/p&gt;

&lt;p&gt;Briefly, you could create a new pipeline that resolves language in a series of discrete steps. Changing how Sitecore identifies language can then be easily modified and extended.&lt;/p&gt;

&lt;p&gt;In a future post, we&amp;rsquo;ll create just such a pipeline.&lt;/p&gt;</description><link>https://insitecore.tumblr.com/post/38230058697</link><guid>https://insitecore.tumblr.com/post/38230058697</guid><pubDate>Tue, 18 Dec 2012 11:02:00 -0500</pubDate><category>Sitecore</category><category>pipelines</category><category>httpRequestBegin</category><category>languages</category></item><item><title>Thoughts on httpRequestBegin - Custom Item Lookups</title><description>&lt;p&gt;Yesterday we looked at the &lt;a href="http://insitecore.tumblr.com/post/37734162227/sitecore-httprequestbegin-pipeline-in-detail"&gt;details behind the httpRequestBegin pipeline&lt;/a&gt;. Today, I wanted to share a few thoughts on the pipeline and extending it.&lt;/p&gt;

&lt;h2&gt;&lt;a id="CustomItemLookups"&gt;Custom Item Lookups&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;A relatively common scenario for developers is the need to override the standard Item lookup process as defined in the &lt;code&gt;ItemResolver&lt;/code&gt;. There are two ways to accomplish this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Sublcass Sitecore&amp;rsquo;s standard &lt;code&gt;ItemResolver&lt;/code&gt; and implement your custom code in a &lt;code&gt;Process()&lt;/code&gt; method override.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new processor and inject it into &lt;code&gt;httpRequestBegin&lt;/code&gt; before the existing &lt;code&gt;ItemResolver&lt;/code&gt;. This technique works because &lt;code&gt;ItemResolver&lt;/code&gt; will not change &lt;code&gt;Context.Item&lt;/code&gt; if it has already been set.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Generally, I recommend option #2 because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It&amp;rsquo;s more portable. Your new code will not have any dependancies on Sitecore&amp;rsquo;s &lt;code&gt;ItemResolver&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s more modular. The code for your custom lookup logic is separated in to its own class and Include files.&lt;/li&gt;
&lt;li&gt;It modifies the pipelines in a predictable way. A new programmer coming on board will be able to identify changes to the pipeline but know that all of the regular processors continue to work in the expected way.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;a id="Implementation"&gt;Implementation&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;(See the next section on how Sitecore Rocks simplifies this process.)&lt;/p&gt;

&lt;p&gt;First, create a new &lt;code&gt;HttpRequestProcessor&lt;/code&gt; subclass that will handle your custom lookup logic. For example:&lt;/p&gt;

&lt;pre class="prettyprint linenums lang-cs"&gt;
using Sitecore;
using Sitecore.Pipelines.HttpRequest;

namespace InSitecore.Sample {
    public class CustomItemResolver : HttpRequestProcessor {

        public override void Process( HttpRequestArgs args ) {
            if( Context.Item == null ) {
                return;
            }

            // Implement custom custom item lookup logic here
        }
    }
}
&lt;/pre&gt;

&lt;p&gt;Next, create an Include file that will insert your processor before &lt;code&gt;ItemResolver&lt;/code&gt;. For example:&lt;/p&gt;

&lt;pre class="prettyprint lang-xml linenums"&gt;
&amp;lt;configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"&amp;gt;
  &amp;lt;sitecore&amp;gt;
    &amp;lt;pipelines&amp;gt;
      &amp;lt;httpRequestBegin&amp;gt;
        &amp;lt;processor type="InSitecore.Sample,InSitecore.Sample"
          patch:before=
"processor[@type='Sitecore.Pipelines.HttpRequest.ItemResolver, Sitecore.Kernel']" /&amp;gt;
      &amp;lt;/httpRequestBegin&amp;gt;
    &amp;lt;/pipelines&amp;gt;
  &amp;lt;/sitecore&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Save that file as &lt;code&gt;CustomItemProcessor.config&lt;/code&gt; in your Sitecore instance&amp;rsquo;s &lt;code&gt;Website/App_Config/Include&lt;/code&gt; directory.&lt;/p&gt;

&lt;h2&gt;&lt;a id="SitecoreRocks"&gt;Sitecore Rocks&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;If you use &lt;a href="http://vsplugins.sitecore.net/default.aspx"&gt;Sitecore Rocks&lt;/a&gt;, you&amp;rsquo;ll find the process of creating pipeline processors much easier.&lt;/p&gt;

&lt;p&gt;Instead of adding a class, choose &lt;code&gt;Add New Item...&lt;/code&gt;. In the dialog, open the Sitecore templates, then the Pipelines subfolder. Choose &lt;code&gt;Http Request Processor&lt;/code&gt; and both the class file and the include file will be created automatically.&lt;/p&gt;</description><link>https://insitecore.tumblr.com/post/37848690556</link><guid>https://insitecore.tumblr.com/post/37848690556</guid><pubDate>Thu, 13 Dec 2012 14:49:00 -0500</pubDate><category>Sitecore</category><category>pipelines</category><category>httpRequestBegin</category></item><item><title>Sitecore httpRequestBegin Pipeline - In Detail</title><description>&lt;p&gt;Pipelines are Sitecore&amp;rsquo;s way of executing operations in an easily extensible way. Sitecore passes off execution of an operation to a Pipeline as defined in web.config. There, each of the processors listed are executed in sequence. In this way, you can easily modify how Sitecore executes operations by modifying the pipelines.&lt;/p&gt;

&lt;p&gt;This is the first in a series of blog posts detailing exactly how the Sitecore pipelines operate. In each post, I&amp;rsquo;ll take one pipeline and describe each of its processors in a fair amount of detail. I might also add a follow-up post on my thoughts on the pipeline.&lt;/p&gt;

&lt;p&gt;In today&amp;rsquo;s post, we&amp;rsquo;ll look at the pipeline at the heart of the Sitecore execution process - &lt;code&gt;httpRequestBegin&lt;/code&gt;. This pipeline is responsible for properly populating the &lt;code&gt;Sitecore.Context&lt;/code&gt; object and making sure execution gets passed to the correct class or file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;httpRequestBegin&lt;/code&gt; has 21 processors (19 if DMS isn&amp;rsquo;t installed), so this is going to be a pretty long post!&lt;/p&gt;

&lt;p&gt;What follows is not official Sitecore documentation and is taken from looking at Sitecore.Kernel code in a decompiler (Reflector and dotPeek). You should use this post as informational not official.&lt;/p&gt;

&lt;!-- more --&gt;

&lt;p&gt;With that out of the way, let&amp;rsquo;s take a look at each of &lt;code&gt;httpRequestBegin&lt;/code&gt;&amp;rsquo;s processors. You can follow along by searching your &lt;code&gt;web.config&lt;/code&gt; file for &lt;code&gt;httpRequestBegin&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;&lt;a id="CheckIgnoreFlag"&gt;CheckIgnoreFlag&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.PreprocessRequest.CheckIgnoreFlag&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
Determines if a blanket pipeline active flag has been set.&lt;/p&gt;

&lt;p&gt;There are two reasons it might not be set, and both are handled in a the &lt;code&gt;preprocessRequest&lt;/code&gt; pipeline&amp;rsquo;s &lt;code&gt;FilterUrlExtensions&lt;/code&gt; processor.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The request might have a blocked extension. In the &lt;code&gt;FilterUrlExtensions&lt;/code&gt; config entry, there are settings for allowed and blocked extensions. If this request has a blocked extension, then then flag will be set to &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A request might be set up to be handled by a Custom Handler. Custom Handlers are defined in &lt;code&gt;web.config&lt;/code&gt; in &lt;code&gt;/configuration/sitecore/customHandlers&lt;/code&gt;. If this request matches the &lt;code&gt;trigger&lt;/code&gt; attribute of any of those handlers, then pipelines don&amp;rsquo;t need to run, since requests will be processed by the Custom Handler rather than regular Sitecore processes. If there&amp;rsquo;s a Custom Handler match, then the flag will be set to &amp;lsquo;false&amp;rsquo;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By default, Sitecore sets a &lt;code&gt;SitecoreOn&lt;/code&gt; flag to &lt;code&gt;true&lt;/code&gt;. If either of the above conditions are met, that flag will be set to &lt;code&gt;false&lt;/code&gt;. The &lt;code&gt;SitecoreOn&lt;/code&gt; flag is set in the &lt;code&gt;Context.Items&lt;/code&gt; collection.&lt;/p&gt;

&lt;p&gt;This processor checks the SitecoreOn key&amp;rsquo;s value to determine if the &lt;code&gt;httpRequestBegin&lt;/code&gt; pipeline should run. If the value is false, then the entire &lt;code&gt;httpRequestBegin&lt;/code&gt; pipeline is aborted.&lt;/p&gt;

&lt;h2&gt;&lt;a id="StartMeasurements"&gt;StartMeasurements&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.StartMeasurements&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
Prepares some performance checks in Sitecore&amp;rsquo;s Items collection. These are retrieved in the &lt;code&gt;httpRequestEnd&lt;/code&gt; pipeline&amp;rsquo;s &lt;code&gt;StopMeasurements&lt;/code&gt; processor and tested against some thresholds. If any threshold is exceeded, it&amp;rsquo;s written out to the log file as a warning. You can change what threshold is tested in the StopMeasurements configuration in web.config.&lt;/p&gt;

&lt;p&gt;Here are the checks that get tracked:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SC_REQUEST_MEASUREMENT_TIMER&lt;/code&gt; key: a new timer object. This will check total elapsed time for the request. The related threshold is &lt;code&gt;TimingThreshold&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SC_REQUEST_MEASUREMENT_ITEMS&lt;/code&gt; key: a count of items accessed. This will check total number of item accesses during the request. The related threshold is &lt;code&gt;ItemThreshold&lt;/code&gt;. (The count of accesses is retrieved from &lt;code&gt;Sitecore.Diagnostics.PerformanceCounters.DataCounters.ItemsAccessed&lt;/code&gt;.)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SC_REQUEST_MEASUREMENT_MEMORY&lt;/code&gt; key: total allocated memory as reported by the garbage collector. This will check total memory consumed during the request. The related threshold is &lt;code&gt;MemoryThreshold&lt;/code&gt;. This value is retrieved from &lt;code&gt;System.GC.GetTotalMemory()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SC_REQUEST_MEASUREMENT_URL&lt;/code&gt; key: the current request&amp;rsquo;s raw URL.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;&lt;a id="StartDiagnostics"&gt;StartDiagnostics&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Analytics.Pipelines.HttpRequest.StartDiagnostics&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Analytics&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; &lt;em&gt;This processor is only present if DMS is installed.&lt;/em&gt;&lt;br/&gt;
Starts the Analytics logger for logging notifications. During DMS processing, log entries are sent through the Analytics logger rather than the standard Sitecore logger.&lt;/p&gt;

&lt;h2&gt;&lt;a id="IgnoreList"&gt;IgnoreList&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.IgnoreList&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
Identifies if the file path of the requested URL is in the ignore list. The ignore list is managed by the &lt;code&gt;IgnoreUrlPrefixes&lt;/code&gt; Sitecore Setting item in web.config. If the URL&amp;rsquo;s file path begins with an entry in &lt;code&gt;IgnoreUrlPrefixes&lt;/code&gt;, the rest of this pipeline is aborted.&lt;/p&gt;

&lt;h2&gt;&lt;a id="SiteResolver"&gt;SiteResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.SiteResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
Determines which Sitecore site, as defined in &lt;code&gt;/configuration/sitecore/sites&lt;/code&gt;, was requested and updates &lt;code&gt;Sitecore.Context.Site&lt;/code&gt; with that information. Sitecore determines this by checking the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A query string parameter for &lt;code&gt;sc_site&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If the &lt;code&gt;EnableSiteConfigFiles&lt;/code&gt; Sitecore Setting is set to &lt;code&gt;true&lt;/code&gt;, then Sitecore will check the request&amp;rsquo;s physical file directory for a &lt;code&gt;site.config&lt;/code&gt; file. Note that the directory it checks will be the full directory path; Sitecore won&amp;rsquo;t ascend the directory structure looking for a &lt;code&gt;site.config&lt;/code&gt; file. For example, if you have a URL for &lt;code&gt;&lt;a href="http://site.net/dir1/dir2/file.aspx"&gt;http://site.net/dir1/dir2/file.aspx&lt;/a&gt;&lt;/code&gt;, you would need to have a physical directory and for dir1 and dir2 and a &lt;code&gt;site.config&lt;/code&gt; file in both directories.&lt;/p&gt;

&lt;p&gt;If the &lt;code&gt;EnableSiteConfigFiles&lt;/code&gt; setting is false, or the directory doesn&amp;rsquo;t exist, or there is no &lt;code&gt;site.config&lt;/code&gt; file in that directory, the algorithm continues with 3, below.&lt;/p&gt;

&lt;p&gt;If you&amp;rsquo;re going to use &lt;code&gt;site.config&lt;/code&gt;, which I&amp;rsquo;d recommend against for its maintenance challenges, the &lt;code&gt;site.config&lt;/code&gt; consists of a single site element with a reference attribute that points to the site element in &lt;code&gt;web.config&lt;/code&gt;. For example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;site reference='website_name' /&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is the main part of the algorithm that will be hit most frequently. Sitecore uses the &lt;code&gt;Sitecore.Sites.SiteContextFactory&lt;/code&gt; class&amp;rsquo;s &lt;code&gt;GetSiteContext&lt;/code&gt; static method to retrieve the &lt;code&gt;SiteContext&lt;/code&gt; information associated with the request. It does this by passing in the requested host name, full request path and port number. Next, it loops across each site defined in &lt;code&gt;configuration/sitecore/sites&lt;/code&gt; and tests if the current request matches.&lt;/p&gt;

&lt;p&gt;Because Sitecore will examine each of the site elements in the order they&amp;rsquo;re listed in &lt;code&gt;web.config&lt;/code&gt;, it&amp;rsquo;s important to have your most generous match (e.g., for the default website site that Sitecore ships with) listed after more specific options.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If none of these techniques work, &lt;code&gt;Sitecore.Context.Site&lt;/code&gt; will end up with &lt;code&gt;null&lt;/code&gt;, which may force later processors to abort.&lt;/p&gt;

&lt;h2&gt;&lt;a id="UserResolver"&gt;UserResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.UserResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
This processor determines the current request&amp;rsquo;s user account by setting the &lt;code&gt;Sitecore.Context.User&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;Because Sitecore uses standard ASP.NET membership, it starts by examining the &lt;code&gt;HttpContext.Current.User&lt;/code&gt; property. If it&amp;rsquo;s been set already, and it&amp;rsquo;s a Sitecore &lt;code&gt;User&lt;/code&gt; object (&lt;code&gt;Sitecore.Security.Accounts.User&lt;/code&gt;) then Sitecore uses that. If it hasn&amp;rsquo;t been set, Sitecore tries to retrieve the user from the username saved in the standard ASP.NET &lt;code&gt;FormsAuthentication&lt;/code&gt; ticket Sitecore sets during authentication.&lt;/p&gt;

&lt;p&gt;In the case that &lt;code&gt;HttpContext.Current&lt;/code&gt; doesn&amp;rsquo;t exist (e.g., code is running outside a regular ASP.NET web request, then Sitecore tries to use the current thread&amp;rsquo;s user.&lt;/p&gt;

&lt;p&gt;If neither of these techniques work, Sitecore returns the default user account. This is going to be the Anonymous user on the current security domain, which is set by the current Site, as discovered in the previous SiteResolver processor.&lt;/p&gt;

&lt;h2&gt;&lt;a id="DatabaseResolver"&gt;DatabaseResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.DatabaseResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
This processor allows you to override the &lt;code&gt;Database&lt;/code&gt; specified by the Site in &lt;code&gt;SiteResolver&lt;/code&gt;. If you want, you can append an &lt;code&gt;sc_database&lt;/code&gt; query string parameter with the name of a database.&lt;/p&gt;

&lt;p&gt;Overriding is only allowed if the current user is an admin or a member of &lt;code&gt;Sitecore Client Users&lt;/code&gt;, since specifying this value allows users to connect to something other than web.&lt;/p&gt;

&lt;h2&gt;&lt;a id="BeginDiagnostics"&gt;BeginDiagnostics&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.BeginDiagnostics&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
This processor determines what happens if you try to run in Debug Mode in the page editor. That is, it checks that settings are correct; that security is correct; and that debug mode is enabled in Sitecore Settings. If all settings check out, Debug Mode, Profiling, etc., are enabled.&lt;/p&gt;

&lt;h2&gt;&lt;a id="DeviceResolver"&gt;DeviceResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.DeviceResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
This processor determines which Device Sitecore will use to resolve presentation. It tries the following approaches, in order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The value of the &lt;code&gt;sc_device&lt;/code&gt; query string parameter - either the name or GUID of a device in the Context database.&lt;/li&gt;
&lt;li&gt;The device attribute on the Context&amp;rsquo;s Site. That is, &lt;code&gt;Sitecore.Context.Site.Device&lt;/code&gt;, as specified in &lt;code&gt;web.config&lt;/code&gt; in the current site&amp;rsquo;s device attribute.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By matching the values in the Device&amp;rsquo;s definition item&amp;rsquo;s fields. First, Sitecore tries to match the &lt;code&gt;Query string&lt;/code&gt; field, then the &lt;code&gt;Browser agent&lt;/code&gt; field.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; to match &lt;code&gt;Query string&lt;/code&gt; field, every key-value pair in the &lt;code&gt;Query string&lt;/code&gt; field has to match the keys in the incoming request&amp;rsquo;s query string. Empty or non-existent keys in the incoming query string will fail to match. Here are some examples:&lt;/p&gt;

&lt;table&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;td&gt;&lt;b&gt; Field &lt;/b&gt;&lt;/td&gt;
            &lt;td&gt;&lt;b&gt; URL QS &lt;/b&gt;&lt;/td&gt;
            &lt;td&gt;&lt;b&gt; Matches? &lt;/b&gt;&lt;/td&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt; mydevice &lt;/td&gt;
            &lt;td&gt; Any request &lt;/td&gt;
            &lt;td&gt; No &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt; mydevice=on &lt;/td&gt;
            &lt;td&gt; ?mydevice &lt;/td&gt;
            &lt;td&gt; No &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt; mydevice=on &lt;/td&gt;
            &lt;td&gt; ?mydevice=on &lt;/td&gt;
            &lt;td&gt; Yes &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt; mydevice=on &lt;/td&gt;
            &lt;td&gt; ?mydevice=anything_else &lt;/td&gt;
            &lt;td&gt; No &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt; mydevice=on &lt;/td&gt;
            &lt;td&gt; ?foo=yes&amp;amp;mydevice=on&amp;amp;bar=no &lt;/td&gt;
            &lt;td&gt; Yes &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt; mydevice=on&amp;amp;subdevice=2 &lt;/td&gt;
            &lt;td&gt; ?mydevice=on &lt;/td&gt;
            &lt;td&gt; No &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt; mydevice=on&amp;amp;subdevice=2 &lt;/td&gt;
            &lt;td&gt; ?mydevice=on&amp;amp;subdevice=2 &lt;/td&gt;
            &lt;td&gt; Yes &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt; &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;To match the Browser agent field, Sitecore just checks if the field value is contained anywhere in the &lt;code&gt;HttpContext.Current.Request.UserAgent&lt;/code&gt;&amp;rsquo;s property value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;defaultDevice&lt;/code&gt; attribute on the Context&amp;rsquo;s Site. That is, &lt;code&gt;Sitecore.Context.Site.DefaultDevice&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A device that has its &lt;code&gt;Default&lt;/code&gt; field checked (raw value of &lt;code&gt;"1"&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note the difference between a site&amp;rsquo;s &lt;code&gt;device&lt;/code&gt; and &lt;code&gt;defaultDevice&lt;/code&gt;. &lt;code&gt;Site.Device&lt;/code&gt; overrides &lt;code&gt;Query string&lt;/code&gt; and &lt;code&gt;Browser agent&lt;/code&gt; field values, while &lt;code&gt;Site.DefaultDevice&lt;/code&gt; is the fallback if those fields fail to match.&lt;/p&gt;

&lt;h2&gt;&lt;a id="LanguageResolver"&gt;LanguageResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.LanguageResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
The &lt;code&gt;LanguageResolver&lt;/code&gt; determines which language Sitecore should use, if it&amp;rsquo;s being set during the current request.&lt;/p&gt;

&lt;p&gt;During the normal processing of a request, when the language is not being set, Sitecore will retrieve the current language like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;sc_Language&lt;/code&gt; key of the &lt;code&gt;Sitecore.Context.Items&lt;/code&gt; collection.&lt;/li&gt;
&lt;li&gt;The value of the a language cookie &lt;code&gt;SiteName#lang&lt;/code&gt; (e.g., for the default website site the cookie key would be &lt;code&gt;website#lang&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The language specified in the &lt;code&gt;language&lt;/code&gt; attribute of the site config element.&lt;/li&gt;
&lt;li&gt;The language specified in the &lt;code&gt;defaultLanguage&lt;/code&gt; Sitecore Setting in &lt;code&gt;web.config&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Failing all other options, the language resolved as &lt;code&gt;en&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;During this processor, Sitecore checks if the language was specified in an &lt;code&gt;sc_lang&lt;/code&gt; query string parameter. If not, it also checks for any language code that was extracted by the &lt;code&gt;preprocessRequest&lt;/code&gt; pipeline&amp;rsquo;s &lt;code&gt;StripLanguage&lt;/code&gt; processor. That processor pulls out the first chunk from the request&amp;rsquo;s URL (from an initial / to the next / or . character).&lt;/p&gt;

&lt;p&gt;If either were set, Sitecore sets the current language which updates the &lt;code&gt;sc_Language&lt;/code&gt; key of the &lt;code&gt;Sitecore.Context.Items&lt;/code&gt; collection and updates the language cookie (see #2, above). This has the effect of setting the &lt;code&gt;Sitecore.Context.Language&lt;/code&gt; property.&lt;/p&gt;

&lt;h2&gt;&lt;a id="CustomHandlers"&gt;CustomHandlers&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.CustomHandlers&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
This processor dispatches requests to specialized handlers that are required. These handlers are defined in &lt;code&gt;web.config&lt;/code&gt; under &lt;code&gt;configuration/sitecore/customHandlers&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If the current request ends with the a handler&amp;rsquo;s file (e.g., &lt;code&gt;sitecore_media.ashx&lt;/code&gt;), then Sitecore aborts the current pipeline, since this request is specifically targeting a handler directly.&lt;/p&gt;

&lt;p&gt;If the current request should be handled by a custom handler (e.g., a URL that starts with &lt;code&gt;~/media&lt;/code&gt; should be handled by &lt;code&gt;sitecore_media.ashx&lt;/code&gt;), then Sitecore rewrites the Context&amp;rsquo;s path information and aborts the pipeline.&lt;/p&gt;

&lt;p&gt;Otherwise, processing continues normally.&lt;/p&gt;

&lt;h2&gt;&lt;a id="FilterUrlExtensions"&gt;FilterUrlExtensions&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.FilterUrlExtensions&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
This processor is deprecated and is here just for backwards compatibility. This processor has an empty Process method.&lt;/p&gt;

&lt;p&gt;On the other hand, the &lt;code&gt;preprocessRequest&lt;/code&gt; pipeline has a &lt;code&gt;FilterUrlExtensions&lt;/code&gt; processor that ensures requests can proceed and that pipelines should be executed.&lt;/p&gt;

&lt;h2&gt;&lt;a id="QueryStringResolver"&gt;QueryStringResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.QueryStringResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
This processor checks for two values that can be specified in query string parameters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;sc_itemid&lt;/code&gt;: specifies the Sitecore Item for the current request. Only if the ID can be found through &lt;code&gt;Sitecore.Context.Database.GetItem()&lt;/code&gt; is &lt;code&gt;Sitecore.Context.Item&lt;/code&gt; set to that Item. Ignored if &lt;code&gt;Sitecore.Context.Item&lt;/code&gt; has been set in a previous processor.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xmlcontrol&lt;/code&gt;: specifies that a Sitecore &lt;code&gt;xmlcontrol&lt;/code&gt; should be used as the layout for rendering.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;&lt;a id="DynamicLinkResolver"&gt;DynamicLinkResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.DynamicLinkResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
This processor checks if the request was for a specific ID using the &lt;code&gt;~/link.aspx&lt;/code&gt; syntax, or a media item by using a media prefix syntax (specified in the &lt;code&gt;configuration/sitecore/mediaLibrary/mediaPrefixes&lt;/code&gt; section of &lt;code&gt;web.config&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;This processor only checks for these links if the &lt;code&gt;Context.Item&lt;/code&gt; hasn&amp;rsquo;t already been set by an earlier processor.&lt;/p&gt;

&lt;p&gt;If an item has been selected using these syntaxes, it&amp;rsquo;s assigned to &lt;code&gt;Sitecore.Context.Item&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;&lt;a id="AliasResolver"&gt;AliasResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.AliasResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
This processor checks if the request was for an alias instead of a regular item.&lt;/p&gt;

&lt;p&gt;First, it checks if aliases are enabled in the &lt;code&gt;AliasesActive&lt;/code&gt; Sitecore setting in &lt;code&gt;web.config&lt;/code&gt;. If aliases aren&amp;rsquo;t active, it skips to the next processor.&lt;/p&gt;

&lt;p&gt;If aliases are active, it checks if any alias matches the current request&amp;rsquo;s &lt;code&gt;LocalPath&lt;/code&gt; property (&lt;code&gt;HttpRequestArgs.LocalPath&lt;/code&gt;). The &lt;code&gt;LocalPath&lt;/code&gt; is the portion of the URL after &lt;code&gt;StartPath&lt;/code&gt;, generally just the path without domain and port information.&lt;/p&gt;

&lt;p&gt;If there&amp;rsquo;s an alias match, it will try to find the Item pointed to by the alias. If it can find that Item, and the &lt;code&gt;Context.Item&lt;/code&gt; hasn&amp;rsquo;t been set yet, then &lt;code&gt;Context.Item&lt;/code&gt; is updated with the Item from the alias. If Context.Item has already been set, then the execution skips to the next pipeline. Note that this means that aliases are searched even if &lt;code&gt;Context.Item&lt;/code&gt; was previously assigned, so a large number of aliases could have performance implications.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;Context.Item&lt;/code&gt; couldn&amp;rsquo;t be updated (and still isn&amp;rsquo;t set), Sitecore will set the Request&amp;rsquo;s &lt;code&gt;FilePath&lt;/code&gt; to the alias&amp;rsquo;s URL, if present. For example, this is the case for an alias with an external link.&lt;/p&gt;

&lt;h2&gt;&lt;a id="DefaultResolver"&gt;DefaultResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.DefaultResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
This processor sets &lt;code&gt;Context.Item&lt;/code&gt; to the default Item for the current &lt;code&gt;Context.Site&lt;/code&gt;, if set.&lt;/p&gt;

&lt;p&gt;The default Item is applied only if all of these things are true:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Context.Item&lt;/code&gt; hasn&amp;rsquo;t been set yet&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Context.Database&lt;/code&gt; has been set (usually from &lt;code&gt;Context.Site.Database&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Context.Site&lt;/code&gt; has been set and &lt;code&gt;Context.Site.StartPath&lt;/code&gt; is non-empty (i.e., positive length)&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;LocalPath&lt;/code&gt; is empty or equals &lt;code&gt;/default&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If all of these things are true, it will attempt to retrieve the site&amp;rsquo;s &lt;code&gt;StartPath&lt;/code&gt; item. &lt;code&gt;StartPath&lt;/code&gt; is the concatenation of the site&amp;rsquo;s &lt;code&gt;rootPath&lt;/code&gt; and &lt;code&gt;startItem&lt;/code&gt; attributes. For example &lt;code&gt;/sitecore/content/home&lt;/code&gt; in the default install of Sitecore&amp;rsquo;s &lt;code&gt;website&lt;/code&gt; site. If the Item can be retrieved, it&amp;rsquo;s assigned to &lt;code&gt;Context.Item&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;&lt;a id="FileResolver"&gt;FileResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.FileResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
The &lt;code&gt;FileResolver&lt;/code&gt; checks if there is a physical file at the request path. If there is, then that file will be executed as the Layout for the page instead of any Presentation assigned to the item itself. &lt;code&gt;Sitecore.Context&lt;/code&gt; will be available and fully populated, even if a physical file is executed.&lt;/p&gt;

&lt;p&gt;The existence of the &lt;code&gt;FileResolver&lt;/code&gt; allows you to have Sitecore execute files directly instead of using the normal Sitecore rendering process from an Item in the database.&lt;/p&gt;

&lt;p&gt;Note that file names must fully match, including extension. For example, if there&amp;rsquo;s an item in the Content Tree at &lt;code&gt;/sitecore/content/home/test1&lt;/code&gt; and a file in the root of the Sitecore application named &lt;code&gt;test1.aspx&lt;/code&gt;, here&amp;rsquo;s what will happen with different URL&amp;rsquo;s:&lt;/p&gt;

&lt;table&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th&gt; &lt;b&gt;URL&lt;/b&gt; &lt;/th&gt;
            &lt;th&gt; &lt;b&gt;Result&lt;/b&gt; &lt;/th&gt;
        &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td&gt; site.com/test1  &lt;/td&gt;
            &lt;td&gt; Content Item&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt; site.com/test1/  &lt;/td&gt;
            &lt;td&gt; Content Item &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td&gt; site.com/test1.aspx  &lt;/td&gt;
            &lt;td&gt; Physical File &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;In this way, physical files take precedence over Content Items. Note that in the third example, above, that even though &lt;code&gt;test1.aspx&lt;/code&gt; is executed, &lt;code&gt;Sitecore.Context.Item&lt;/code&gt; will be populated with the &lt;code&gt;/sitecore/content/home/test1&lt;/code&gt; item in the &lt;code&gt;ItemResolver&lt;/code&gt; processor of this pipeline.&lt;/p&gt;

&lt;h2&gt;&lt;a id="ItemResolver"&gt;ItemResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.ItemResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
Although all of the processors in this pipeline are important, this is the one that many people will feel is the &amp;ldquo;heart&amp;rdquo; of the pipeline.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ItemResolver&lt;/code&gt; translates the requested URL in to a Content Item from the Content Tree &amp;ndash; in other words, this is what finds the item a visitor is looking for when they click on a link.&lt;/p&gt;

&lt;p&gt;In the following notes, &lt;em&gt;Sitecore Decoded&lt;/em&gt; means that encoding replacements have been completed. Encoding replacements are specified in &lt;code&gt;web.config&lt;/code&gt; in &lt;code&gt;/configuration/sitecore/encodeNameReplacements&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sitecore finds the requested Item by following these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If &lt;code&gt;Context.Item&lt;/code&gt; has already been set, skip to the next processor.&lt;/li&gt;
&lt;li&gt;Try to do a straight lookup from the Sitecore Decoded &lt;code&gt;ItemPath&lt;/code&gt;, which is the non-domain portion of a URL, stripped of query string, extensions and trailing / characters.&lt;/li&gt;
&lt;li&gt;Attempt to a lookup from the &lt;code&gt;LocalPath&lt;/code&gt;, which is the &lt;code&gt;ItemPath&lt;/code&gt; with &lt;code&gt;StartPath&lt;/code&gt; removed.&lt;/li&gt;
&lt;li&gt;Attempt the same, but Sitecore Decoded.&lt;/li&gt;
&lt;li&gt;Try with the &lt;code&gt;Context.Site.RootPath&lt;/code&gt; prepended to &lt;code&gt;LocalPath&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Try the same, but Sitecore Decoded.&lt;/li&gt;
&lt;li&gt;Resolve by a name search. In this step, the resolver tries to get the start item specified in &lt;code&gt;Context.Site.RootPath&lt;/code&gt;. If it can find it, it scans each child looking for a match on each chunk of the request&amp;rsquo;s Sitecore Decoded &lt;code&gt;LocalPath&lt;/code&gt; using the Item&amp;rsquo;s Display Name and Name properties.&lt;/li&gt;
&lt;li&gt;Same as 6, but tries with only the &lt;code&gt;ItemPath&lt;/code&gt; portion of the URL.&lt;/li&gt;
&lt;li&gt;Finally, if the &lt;code&gt;sc_usesitestartpath&lt;/code&gt; query string parameter has been set to &lt;code&gt;true&lt;/code&gt;, then the &lt;code&gt;Context.Site.StartItem&lt;/code&gt; Item is returned.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If all of these steps fail, the &lt;code&gt;Sitecore.Context.Item&lt;/code&gt; will be set to &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;&lt;a id="PageLevelTestItemResolver"&gt;PageLevelTestItemResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Analytics.Pipelines.HttpRequest.PageLevelTestItemResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Analytics&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; &lt;em&gt;This processor is only present if DMS is installed.&lt;/em&gt;&lt;br/&gt;
This processor checks if page-level A/B tests have been initialized on the current item and does any runtime setup required for those tests if they exist.&lt;/p&gt;

&lt;h2&gt;&lt;a id="LayoutResolver"&gt;LayoutResolver&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.LayoutResolver&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
This processor determines which Sitecore Layout will be used to satisfy the current request.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;Context.Item&lt;/code&gt; hasn&amp;rsquo;t been set, or if &lt;code&gt;Context.Page.FilePath&lt;/code&gt; (the layout to be used) has already been set, then processing skips to the next processor.&lt;/p&gt;

&lt;p&gt;This processor tries to find a layout using these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Determine if the &lt;code&gt;sc_layout&lt;/code&gt; query string parameter supplied a valid reference (path or GUID) to a Layout definition Item.&lt;/li&gt;
&lt;li&gt;If not, see of the &lt;code&gt;Context.Item&lt;/code&gt; has a Layout assigned through the &lt;code&gt;Context.Item.Visualization.Layout&lt;/code&gt; property, which is set through normal Presentation Layout Details dialogs.&lt;/li&gt;
&lt;li&gt;If a valid Layout Item has been found, Sitecore will first try to use any XML Controls that have been assigned to it through the Control or Path fields. The processor will also work to decode and transcribe XML Control references (e.g., &lt;code&gt;xmlcontrol&lt;/code&gt; query strings).&lt;/li&gt;
&lt;li&gt;Otherwise, the Layout&amp;rsquo;s Path will be assigned as a standard .aspx file&lt;/li&gt;
&lt;li&gt;Finally, if no Layout could be found, Sitecore will use the Layout specified in the &lt;code&gt;DefaultLayoutFile&lt;/code&gt; Sitecore Setting, if present.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sitecore assigns Layout to a request by updating &lt;code&gt;Sitecore.Context.Page.FilePath&lt;/code&gt;. If none of these techniques work, that property will return &lt;code&gt;null&lt;/code&gt; or the empty string.&lt;/p&gt;

&lt;h2&gt;&lt;a id="ExecuteRequest"&gt;ExecuteRequest&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Class:&lt;/strong&gt; &lt;code&gt;Sitecore.Pipelines.HttpRequest.ExecuteRequest&lt;/code&gt;&lt;br/&gt;
&lt;strong&gt;Assembly:&lt;/strong&gt; &lt;code&gt;Sitecore.Kernel&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt;&lt;br/&gt;
This is where the rubber meets the road. This processor finalizes activity and makes sure the &lt;code&gt;Sitecore.Context&lt;/code&gt; is ready for the execution process to begin. It checks the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;That &lt;code&gt;Context.Site&lt;/code&gt; has been assigned and the current user has Site Enter permissions. If Site Enter is not granted, Sitecore will redirect to an Access Denied message.&lt;/li&gt;
&lt;li&gt;If no &lt;code&gt;Context.Item&lt;/code&gt; has been assigned, Sitecore will redirect to a Item Not Found error message.&lt;/li&gt;
&lt;li&gt;If no Layout has been assigned (in &lt;code&gt;Context.Page.FilePath&lt;/code&gt;), then Sitecore will redirect to a Layout Not Found error message.&lt;/li&gt;
&lt;li&gt;If the Layout assigned is not internal to this application, Sitecore will emit a Response.Redirect to the URL specified in &lt;code&gt;Context.Page.FilePath&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Finally, if none of that happens, Sitecore updates the &lt;code&gt;HttpContext&lt;/code&gt;&amp;rsquo;s paths with a call to RewritePath with the location of the physical file to execute.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;&lt;a id="EndofPipeline"&gt;End of Pipeline&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;After this, ASP.NET will continue execution normally as &lt;code&gt;HttpContext&lt;/code&gt; has the correct paths and &lt;code&gt;Sitecore.Context&lt;/code&gt; has been fully populated.&lt;/p&gt;</description><link>https://insitecore.tumblr.com/post/37734162227</link><guid>https://insitecore.tumblr.com/post/37734162227</guid><pubDate>Tue, 11 Dec 2012 16:06:00 -0500</pubDate><category>sitecore</category><category>pipelines</category><category>httprequestbegin</category><category>backend</category></item><item><title>.NET 4.5 Compatibility</title><description>&lt;p&gt;Right now, Sitecore has an incompatibility with .NET 4.5  If you have .NET 4.5 installed, you will find that you can&amp;rsquo;t log in to any of your Sitecore instances.&lt;/p&gt;

&lt;p&gt;.NET 4.5 modifies some code that the login page calls and will throw an Exception. Previously, the only solution was to uninstall .NET 4.5 and reinstall .NET 4.0. However, it turns out that the code path that causes the Exception is only reached if you&amp;rsquo;re asking the login page to remember the last username used in a cookie. If you turn this feature off, you&amp;rsquo;ll be able to login again.&lt;/p&gt;

&lt;p&gt;Simply modify the Login.RememberLastLoggedInUserName setting in web.config to false. Here&amp;rsquo;s an example include file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"&amp;gt;
     &amp;lt;sitecore&amp;gt;
        &amp;lt;settings&amp;gt;
            &amp;lt;setting name="Login.RememberLastLoggedInUserName"&amp;gt;
                 &amp;lt;patch:attribute name="value"&amp;gt;false&amp;lt;/patch:attribute&amp;gt;
            &amp;lt;/setting&amp;gt;
        &amp;lt;/settings&amp;gt;
     &amp;lt;/sitecore&amp;gt;
 &amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To use this include file, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Notepad (or your preferred text editor)&lt;/li&gt;
&lt;li&gt;Paste the configuration code above, including the opening &amp;lt;configuration&amp;gt; and closing &amp;lt;/configuration&amp;gt; tags&lt;/li&gt;
&lt;li&gt;Save the file under you Sitecore instance&amp;rsquo;s directory in \Website\App_Config\Include. Name the file aspnet_45_fix.config&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(Thanks to Michael Mavrofrides for pointing me to this fix)&lt;/p&gt;</description><link>https://insitecore.tumblr.com/post/32935664834</link><guid>https://insitecore.tumblr.com/post/32935664834</guid><pubDate>Fri, 05 Oct 2012 09:06:00 -0400</pubDate></item><item><title>Automatically Logging in to the Sitecore Desktop</title><description>&lt;p&gt;For development, I have Internet Explorer set to flush cache and history at close. That means that whenever I launch IE and log in to Sitecore, and have to select the Desktop again under options. That can get annoying, especially for local Sitecore installs where I&amp;rsquo;m doing development. I generally always want to log in to the Desktop.&lt;/p&gt;

&lt;p&gt;Unfortunately there is no global setting to fix this. That is, there is no always log in all users to the Desktop setting. That&amp;rsquo;s because the login page (/sitecore/login/default.aspx) base class (Sitecore.sitecore.login.LoginPage) hard codes Content Editor as the default interface.&lt;/p&gt;

&lt;p&gt;There are two solutions. One easy, one hard. I&amp;rsquo;d recommend the first (easy) solution, but the second solution is interesting from a Sitecore internals perspective.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Option 1:&lt;/em&gt; Set the User&amp;rsquo;s Profile&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this technique, we assign use the User Account&amp;rsquo;s Profile tab to specify which user interface they should log in to. Once you&amp;rsquo;ve set this, the user &lt;em&gt;will always&lt;/em&gt; log in to that page, regardless of what they select in the Options section of the Login page.&lt;/p&gt;

&lt;p&gt;This is the technique I use for dev instances of Sitecore.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Login to Sitecore with an account that has access to the User Manager application (e.g., admin)&lt;/li&gt;
&lt;li&gt;Open the User Manager&lt;/li&gt;
&lt;li&gt;Double-click the account you want to edit&lt;/li&gt;
&lt;li&gt;Click on the Profile tab&lt;/li&gt;
&lt;li&gt;In the Start Url radio options, choose Desktop
&lt;img src="https://64.media.tumblr.com/tumblr_m66gtad9U91r4w365.png" alt="The User Profile tab" title="The User Profile tab"/&gt;&lt;/li&gt;
&lt;li&gt;Click OK&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This user will now always log in to the Desktop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Option 2:&lt;/em&gt; Change the Login Processor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sitecore handles logging users in using processors. We can hook in to the post-login processor, LoggedIn, and redirect to a url. Here&amp;rsquo;s an example code file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;using System.Web;
using Sitecore.Pipelines.LoggedIn;
using Sitecore.Web;

namespace InSitecore.Examples.Pipelines.LoggedIn {

  public class RedirectOnLogIn : LoggedInProcessor {

    // Which query string param should we be looking for
    // we default to "url" becuase that's where Sitecore
    // will put its redirect url if you've enabled
    // the Authentication.SaveRawUrl setting.
    private string _queryStringParamName = "url";

    public string QueryStringParamName {
      get { return _queryStringParamName; }
      set { _queryStringParamName = value; }
    }

    public override void Process(LoggedInArgs args) {
      // Bail on all processors as soon as possible for max performance
      if (Sitecore.Context.GetSiteName() != "login") { return; }

      string url = HttpUtility.UrlDecode(
          WebUtil.GetQueryString(this.QueryStringParamName, "")
      );
      if (!string.IsNullOrWhiteSpace(url)) {
        WebUtil.Redirect(url);
      }
    }

  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And an example include file to hook it up:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"&amp;gt;
  &amp;lt;sitecore&amp;gt;
    &amp;lt;processors&amp;gt;
      &amp;lt;loggedin&amp;gt;
        &amp;lt;processor mode="on"
            type="InSitecore.Examples.Pipelines.LoggedIn.RedirectOnLogIn,
                  InSitecore.Examples" /&amp;gt;
      &amp;lt;/loggedin&amp;gt;
    &amp;lt;/processors&amp;gt;
  &amp;lt;/sitecore&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, instead of logging in to http://sitecoreinstance/sitecore, you should use a url like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;http://sitecoreinstance/sitecore/login?url=shell/default.aspx
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That will log you in and drop you on the Desktop.&lt;/p&gt;

&lt;p&gt;You&amp;rsquo;ll notice that the processor class has a QueryStringParamName parameter. You can use this to control which query string parameter the processor will pay attention to. For example, if you&amp;rsquo;d prefer to use the query string param &amp;ldquo;redirect&amp;rdquo; (e.g., http://sitecoreinstance/sitecore/login?redirect=shell/default.aspx), you can modify the include file like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"&amp;gt;
  &amp;lt;sitecore&amp;gt;
    &amp;lt;processors&amp;gt;
      &amp;lt;loggedin&amp;gt;
        &amp;lt;processor mode="on"
            type="InSitecore.Examples.Pipelines.LoggedIn.RedirectOnLogIn,
                  InSitecore.Examples"&amp;gt;
          &amp;lt;QueryStringParamName&amp;gt;redirect&amp;lt;/QueryStringParamName&amp;gt;
        &amp;lt;/processor&amp;gt;
      &amp;lt;/loggedin&amp;gt;
    &amp;lt;/processors&amp;gt;
  &amp;lt;/sitecore&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description><link>https://insitecore.tumblr.com/post/25853860052</link><guid>https://insitecore.tumblr.com/post/25853860052</guid><pubDate>Mon, 25 Jun 2012 10:52:32 -0400</pubDate></item><item><title>Manually Uninstalling Sitecore</title><description>&lt;p&gt;For the last few days, I&amp;rsquo;ve been doing a lot of work with DMS using our internal training site, SiteSetter. SiteSetter is a manual install of Sitecore. That is, no .exe installer wizard to help you get things set up. The process of manually installing Sitecore is pretty straight forward once you&amp;rsquo;ve done it a few times.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve created at least four different SiteSetter installs this week, and now I&amp;rsquo;m getting to the point where I&amp;rsquo;m ready to remove them. Unfortunately, because they were installed manually, they need to be uninstalled manually too.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s my guide for manually uninstalling Sitecore. In this case, it&amp;rsquo;s a DMS-acitve one, so there&amp;rsquo;s an extra database that we need to deal with (Sitecore_Analytics), but other than that, these instructions should work for any manually installed Sitecore instance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; that you should never &lt;em&gt;manually&lt;/em&gt; uninstall a Sitecore instance that was installed with an installer program. Instead, use the Add/Remove Programs or Programs and Features tool of your OS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Uninstalling Sitecore&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This instructions assume you&amp;rsquo;ve installed Sitecore using the standard conventions. You might find your files in slightly different places. You may have named your databases something else, so update these instructions to fit your install scenario.&lt;/p&gt;

&lt;p&gt;We will be manually deleting databases and files &amp;ndash; &lt;strong&gt;There is no undo&lt;/strong&gt; from this process. Your files and databases will be permanently deleted.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Remove the IIS configuration&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the IIS Manager (inetmgr from the Start search box)&lt;/li&gt;
&lt;li&gt;In the left-hand pane, open the node for your local machine.&lt;/li&gt;
&lt;li&gt;Open the node for Sites&lt;/li&gt;
&lt;li&gt;Find your Sitecore instance&amp;rsquo;s website. Right-click on it and select Remove. A confirmation dialog will open. Click Yes.&lt;/li&gt;
&lt;li&gt;In the left-hand pane, click on Application Pools&lt;/li&gt;
&lt;li&gt;In the right-hand pane, find your instance&amp;rsquo;s Application Pool. Right-click on it and select Remove. A confirmation dialog will open. Click Yes.&lt;/li&gt;
&lt;li&gt;Close IIS Manager&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Remove the hosts file entry&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Notepad with Administrator privileges:

&lt;ol&gt;
&lt;li&gt;Find Notepad in the Start menu: Start &amp;gt; All Programs &amp;gt; Accessories &amp;gt; Notepad&lt;/li&gt;
&lt;li&gt;Right-click on the Notepad shortcut and select Run as Administrator. Notepad opens.&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;Click File | Open. The File Open dialog opens.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter this path in to the File name text box:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;%windir%\system32\drivers\etc\hosts
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Find your Sitecore instance&amp;rsquo;s reference in the list of host headers. It will look something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;127.0.0.1    SitecoreInstanceName
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Delete that line&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;Save and close&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Detach your databases&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open SQL Server Management Studio&lt;/li&gt;
&lt;li&gt;Connect to your local database server&lt;/li&gt;
&lt;li&gt;Open a new query window: File | New | Query with Current Connection.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Paste the following SQL code in to the query window:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;USE master

DECLARE
      @name SYSNAME
    , @sql VARCHAR(MAX)

SET @name = '&amp;lt;YOUR INSTANCE NAME HERE&amp;gt;'

SET @sql = '
    DROP DATABASE {0}Sitecore_Analytics
    DROP DATABASE {0}Sitecore_Core
    DROP DATABASE {0}Sitecore_Master
    DROP DATABASE {0}Sitecore_Web
    '

SET @sql = REPLACE( @sql, '{0}', @name )

EXEC( @sql )
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make sure that the @name variable (on line 7) has been set to your Sitecore instance&amp;rsquo;s name. If you don&amp;rsquo;t have DMS installed, delete line 10, the one that ends with Sitecore_Analytics.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;Close SQL Server Management Studio.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Delete the file system&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In Windows Explorer, find the folder for your Sitecore intstance, usually&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;C:\inetpub\wwwroot\&amp;lt;YOUR INSTANCE NAME&amp;gt;\
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Delete that folder&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that&amp;rsquo;s it. Your manually installed Sitecore instance has been removed from your system.&lt;/p&gt;</description><link>https://insitecore.tumblr.com/post/25640874877</link><guid>https://insitecore.tumblr.com/post/25640874877</guid><pubDate>Fri, 22 Jun 2012 07:46:00 -0400</pubDate><category>sitecore</category><category>dms</category><category>uninstall</category></item><item><title>Spoofing DMS GeoIP Lookups for Localhost</title><description>&lt;p&gt;When you&amp;rsquo;re working with a copy of DMS locally or on your local network, your reports will be filled with empty GeoIP information because MaxMind doesn&amp;rsquo;t have information for local or internal addresses.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://sitecoresnippets.blogspot.ca/"&gt;Alexander Doroshenko&lt;/a&gt; has a great solution to this problem related in this &lt;a href="http://sitecoresnippets.blogspot.ca/2012/04/update-geoip-info-in-dms-database.html"&gt;blog post&lt;/a&gt;. Basically, you can manually add a cached IP lookup to the Analytics database and update any historical entries. There&amp;rsquo;s a SQL file you can download from that blog post that does the work for you.&lt;/p&gt;

&lt;p&gt;You&amp;rsquo;ll need to specify the IP address you&amp;rsquo;re updating plus the results of the lookup. For example, ISP, Country, Region, City, etc. You can get this info directly from MaxMind. Visit &lt;a href="http://www.maxmind.com/app/lookup_city"&gt;MaxMind&amp;rsquo;s City Lookup Page&lt;/a&gt; and put in the IP address you want to spoof.&lt;/p&gt;

&lt;p&gt;(Not sure which IP to spoof? Try your external IP &amp;ndash; just Google &lt;a href="https://www.google.com/search?q=what's+my+ip"&gt;&amp;ldquo;What&amp;rsquo;s my IP?&amp;rdquo;&lt;/a&gt; and Google will give you you&amp;rsquo;re current external IP address.)&lt;/p&gt;</description><link>https://insitecore.tumblr.com/post/25464697313</link><guid>https://insitecore.tumblr.com/post/25464697313</guid><pubDate>Tue, 19 Jun 2012 19:08:00 -0400</pubDate><category>sitecore</category><category>dms</category><category>geoip</category><category>spoof</category><category>links</category></item><item><title>Refreshing TreeviewEx Controls</title><description>&lt;p&gt;When you’re creating your own Sitecore applications, you might need to use a TreeviewEx control, like the one in the Content Editor that displays the Content Tree.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://64.media.tumblr.com/tumblr_m5sbz8GemX1r4w365.jpg" alt="The Content Editor with the TreeviewEx control highlighted" title="The Content Editor with the TreeviewEx control highlighted"/&gt;&lt;/p&gt;

&lt;p&gt;You might want to change the selected item in your code. You can do so using code like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var selectedItem = Context.ContentDatabase.GetItem("/sitecore/content/home");
this.MyTreeviewEx.SetSelectedItem(selectedItem);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunately, that won’t update the display. To make sure the display updates, set the TreeviewEx’s &lt;em&gt;data context’s&lt;/em&gt; Folder. The DataContext for your TreeviewEx is usually set decoratively in your XAML. In my case, the DataContext has an ID of TreeDataContext:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;this.TreeDataContext.SetFolder(selectedItem.Uri);
&lt;/code&gt;&lt;/pre&gt;</description><link>https://insitecore.tumblr.com/post/25324894252</link><guid>https://insitecore.tumblr.com/post/25324894252</guid><pubDate>Sun, 17 Jun 2012 19:36:00 -0400</pubDate><category>sitecore</category><category>client ui</category><category>applications</category><category>treeviewex</category></item><item><title>MVC Released Internally</title><description>&lt;p&gt;Sitecore announced over the weekend that MVC support is being added with an internal build of Sitecore - v.6.5.1.&lt;/p&gt;

&lt;p&gt;Read more from &lt;a href="http://www.sitecore.net/Community/Business-Blogs/Technical-Trends/Posts/2012/06/MVC-and-Sitecore-651-Overview.aspx"&gt;Lars Nielsen&lt;/a&gt;, and some technical challenges of setting up WinForms and MVC support in a single instance from &lt;a href="http://www.sitecore.net/Community/Technical-Blogs/John-West-Sitecore-Blog/Posts/2012/06/Using-Web-Forms-and-MVC-in-a-Single-Solution-with-the-Sitecore-ASPNET-CMS.aspx"&gt;John West&lt;/a&gt; here.&lt;/p&gt;</description><link>https://insitecore.tumblr.com/post/24886273530</link><guid>https://insitecore.tumblr.com/post/24886273530</guid><pubDate>Mon, 11 Jun 2012 11:25:15 -0400</pubDate><category>sitecore</category><category>mvc</category><category>links</category></item></channel></rss>
