Friday, May 17, 2013

Internet Explorer version ≤8 parseInt() octal radix default

Old browsers, like IE7 and IE8 ( that uses ECMAScript older than 5) uses octal radix ( or base ) as default when parsing strings that start with “0” as ints. Internet Explorer 8 and older versions therefore have this rather peculiar default behavior.

parseInt(“01”) => 1*8^0 = 1
parseInt(“05”) => 5*8^0 = 5
parseInt("055") => (5*8^1)+(5*8^0), 40+5 = 45
parseInt(“07”) => 7*8^0 = 7

parseInt(“08”) => 0*8^0 = 0 (the 8 has no equivalent in base 8)
parseInt(“09”) => 0, same issue

parseInt(“10”) => (0*10^0) + (1*10^1) = 10 ( IE8 recognizes this as base 10, as it doesn’t start with zero.) 

Say that you're parsing months as ints, 01-12. 01-09 will be parsed as base 8, and 10-12 as base 10.
It'll work in all new browsers, but 08 and 09 will be parsed as zero in IE8 or older ( or other old browsers ).

Luckily, for us all, there is a way to specify which base to use.

parseInt(string,base);
parseInt(“08”,10) => 8*10^0 = 8

Friday, May 3, 2013

Marketing Automation – Shifting the way we engage individuals.

Insights from Silverpop’s Digital Marketing University

Silverpop’s Digital Marketing University (#DMU13) in Chicago had a packed house, over 200 people poised with pen, pad, and open mind ready to absorb marketing automation knowledge from the experts. Silverpop’s Director of Product Strategy Brian Brown (@GetVision) began the conference with an explanation of what we’re witnessing today, the “channel explosion.” Blogs, Facebook, Twitter, and Pinterest, the list of channels that marketers are asked to leverage continually grows. The more channels, the more work for the marketing team, but not necessary more reward! The channel explosion has changed how we communicate, learn, and buy, explained Brown. Consumers research product information online, and visit retail outlets when they’re ready to purchase. They know the World Wide Web often supports more informed decision-making than sales associates.

Individuals today are required to aggressively filter overwhelming amounts of content a result of the fusion between mass marketing and the channel explosion. How we’re engaging with them online has to change. To reach our customers we must move away from mass marketing, away from segmented marketing, and strive for individual marketing. Think, “share-worthy.” Our focus should change from generating revenue to creating experiences (that generate revenue), suggests Brown. Creating experiences for consumers means timely delivery of content that is uniquely relevant.

In the world of automated marketing we aren’t blasting emails to lists. Information about our customers’ behavior drives our rules for engagement. Listen… “Set it and forget it,” recommended Silverpop’s Product Evangelist Dave Walters. The information utilized to create rules can be anything from pages visited, questions answered, whitepapers downloaded, emails opened, read, or responded to, forms filled out, or any combination of the above. Content delivered can be equally dynamic: emails, sets of emails, web page content, notifications to sales teams, progressive forms, or anything else digital you can imagine. Automation is shifting the marketer’s job to a higher level.

If we view the benefits of marketing automation through a lens of the time management matrix created by Stephen Covey, author of The 7 Habits of Highly Effective People we see that we are able to spend more time on quadrant 2, important and not urgent, activities. In his book Covey emphasizes that quadrant 2 activities --capability improvement, relationship building, recognizing new opportunities, and planning -- provide the most return per time invested. Isn’t that what we’re seeking?

The time management matrix

Marketing teams in the future will spend more of their with whiteboard discussions to identify the best ways to engage individuals. Content creation is still central to the marketer’s strategy, but rather than being delivered at once, content will live forever (or as long as relevant) in the automation system, and delivered to individuals at appropriate times based on defined rules. Over time our base of content and rules for engagement will grow, we will focus our energy on refining our message rather than pressing the send button, and we will witness huge increases in our conversion rates!

If you happen to see one of Silverpop’s Digital Marketing Universities near you I recommend attending! Thanks to everyone at the Silverpop team for putting on a great event.

Thursday, April 25, 2013

Combining CMS and e-commerce in the best way


Customers are aware of that they need to MVT-test checkout flows, shopping basket placement as well as have a slick interface for WYSIWYG adding and changing product information.

But what else is there to be done?

Burberry, working with a high profile line of fashion products, showed an great example of experience driven commerce during the Adobe Summit in London 2013. They have coined their project "Bring the Online Experience to Stores, and Not Vice Versa".

They have worked hard to build the next generation of beautiful product catalogues on their integrated Adobe CQ5 and hybris e-commerce solution. The idea was that product listings on the web are linear and ugly and product catalogues can be really inspiring pieces of art.



Their partner, new web firm Deloitte Digital with project manager Andrew Clarson, combined the CMS and e-commerce solutions so that the editors got the possibility to combine DAM such as fashion show reels with e-commerce parts (product areas). The CMS then had a scripted frontendcode solution so i.e. imagemap areas could be spotted, marked and by linking product data immediately turned into e-commerce parts. Generating predefined e-commerce product parts. Shown as “products in this show”, directly beneath a fashion show catwalk.

A really nice way to continuously give marketers and product managers the possibility to convert on more than just boring, classic product listings.

Monday, April 15, 2013

Don't Miss Sprint Retrospectives!

It may seem just to skip Sprint Retrospectives, especially when there is “work to be done,” but like all scrum milestones retrospectives must be executed to realize the maximum value of the scrum framework. They contribute to self-organization, team building, reenergizing, and the socialization of issues.

Scrum is a framework for managing chaos, and sprint retrospectives, an empirical process improvement tool, improve the management of chaos. Scrum founding member Mike Beedle explains, “the purpose of [the sprint retrospective] is to improve the development process, and make it more effective and enjoyable for the next sprint. The dimensions of what went right or wrong are people, relationships, process and tools.”

Sprint Retrospectives spark insight, and have an enlightening atmosphere. Perhaps it's the basking in successes of the just finished sprint, the chance of lifting the weight of issues that have been bothering team members, recalling “Ah-Ha” moments, or strengthening of the process overall.

After the 10th retrospective its understandable if feel all the benefits of the sprint retrospective have been acquired. However, chances are even if you’re unenthusiastic about the retrospective, one of your team members has been waiting for this scheduled opportunity to share their thoughts. It is possible that your retrospectives decrease in duration over time, but each sprint retrospective is unique. Changing team dynamics, events, projects, stages of a project, and experiences contribute to the evolution of sprint retrospective benefits over time.

Would you like your team to get more done? Take sprint retrospective time to enjoy space, relax, eat pizza (drink beers), joke around, and reenergize. “We cannot add hours to our day, but we can add energy,” explain Tony Schwartz and Catherine McCarthy of the energy project. Retrospectives provide breathing room for teams who have been working hard. “One of the best ways of adding energy is increasing passion,” explains Mike Cohn in Succeeding with Agile. “The more passionate people are about their projects, the more likely they are to fully engage on them each day.” Increase teams’ passion by providing ownership through retrospectives. All team members have the opportunity to share successes, address issues, give praise, identify ah-ha moments, and provide hypotheses for the next sprint.

At best cutting corners (skipping meetings) of the scrum process leads to bleeding of benefits, at worst, disorientation and room for chaos (in its many forms) to take the reigns of your project. Every scrum milestone contributes to organizing and reinforcing the social fabric of the team. Don’t skip sprint retrospectives!

P.S. If you’re using Trello (amazing tool!) for managing projects, you may find this Sprint Retrospective Template useful!

Wednesday, April 10, 2013

Blank edit after upgrading to EPiServer 7.1

After installing the upgrade you are supposed to restart your application to finish the upgrade process. What happened was that the whole edit window was totally blank. Well not totally I could see the colored edit bar, and everything that is rendered wen it's expanded. Admin mode also worked. The problem was not related to the Preamble property error that Erik pointed out.
The way to resolve this was to empty the ASP.NET temporary files folder (located at C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root  or Framework64), do an iisreset and start the site.

This is one of the things to take into account when deploying an upgrade to your different environments.

By the way the folders affected by the update are:

  • webroot/modulesbin
  • yourVPPFolder/Modules
  • yourVPPFolder/ModulesRepository

Thursday, April 4, 2013

Nansen at An Event Apart Seattle: 2013

Being my first contribution to the esteemed Nansen blog, allow me to introduce myself: I'm Justin Dauer, Creative Director for our Chicago office. This past Monday, our Interface Architect Patrick Waks and I had the opportunity to attend An Event Apart in Seattle.


Nansen sponsors An Event Apart in Seattle


An Event Apart swag

Not only was this an incredible chance to absorb knowledge from thought leaders in our digital industry, but it was particularly sweet as Nansen was an official conference sponsor.


Nansen sponsors An Event Apart in Seattle


The Seattle conference is particularly intimate in terms of venue size, and as such, everything was just that much more accessible. Not only are you surrounded by "your people" in terms of industry peers, but the speakers themselves — titans of thought leadership and shapers of our industry — are equally as accessible. I had the opportunity to chat with Jeffrey Zeldman about the glory days of Mac OS 7-8 pixel-based icon design, the core benefit of sketching and thumbnailing with Jason Santa Maria, and making content and design open and accessible for all with Ethan Marcotte. It was particularly thrilling to see Nansen's design and implementation of the Coop web site be a part of Ethan's presentation Responsive and Responsible as an example of a beacon of responsive design. Not bad, coming from the very person who was the first to coin the phrase "responsive design".

The conference sessions themselves were a one-track format, with 12 speakers presenting over the course of a couple days, and a workshop session run by Luke Wroblewski the final day. While we're confident and passionate about functional creativity, a little validation never hurts, and seeing core facets of our process referenced and lauded again and again across multiple presentations certainly was great to behold. That, coupled with seeing where our industry is headed visually and technically, made for an incredibly rewarding experience.

My one regret would have been not having the chance to see more of the great city of Seattle. We were able to try a few of the local gastro pubs and watering holes, and Patrick and I enjoyed plenty of good conversation and equally good alcohol during the first day's after party at Buckley's in Belltown. I'll close out with a view from the Bell Harbor Convention Center's waterfront, and an invitation to come see us from Nansen as we again sponsor the An Event Apart conference in August – this time right in the backyard of our Chicago office.


the sun sets on Seattle

Scheduled Jobs not running after site upgrade

After an upgrade of a customer site from EPiServer 5 to EPiServer 6 all scheduled jobs stopped working in all environments. When debugging the scheduling service (in a command prompt run "EPiServer.SchedulerSvc.exe DEBUG" in the service directory) we noticed that when the service tried to connect to the site it failed with the following error message,


#INF# [_LM_W3SVC_1_ROOT] Failed calling site (Attempting to deserialize an empty stream.)

We tried to clear the "EPiServer.SchedulerService.Sites.xml" file to force a re-registration of the site but it never registered. After some thinking and contact with EPiServer support we found the fault, a missing module in Web.config. When we added the "FirstBeginRequestModule" module to the modules section everything started working again.

<configuration>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="FirstBeginRequestModule" precondition="managedHandler" type="EPiServer.Web.InitializationModule, EPiServer">
    </modules>
  </system.webServer>
</configuration>

Wednesday, April 3, 2013

How to disable CMS edit/admin mode on "public facing" servers in a load balanced environment

Update: some people have pointed out that they prefer the method of disabling the specific virtual paths in episerver.config.  See the end of this blog post for more information.

Hi Folks!

I realize that there have been several other blog posts regarding this topic, but after lots or trial and error I believe I have found a solid approach for disabling CMS edit/admin mode on public facing IIS servers in a load balanced environment.

There are other techniques that can be used to secure CMS edit/admin modes in a single server environment.  Check out this blog post by David Knipe for additional information.  It essentially uses IP white lists at the IIS level.  Maintaining IP whitelists can be problematic, so I prefer having a dedicated CMS server that's only accessible within the internal network.

In my last blog post we covered how to setup EPiServer load balancing using net.tcp.  We also detailed the three basic models that can be used when implementing EPiServer load balancing.  Today we'll be focusing on the Security model.

To recap, the security model provides a dedicated server for CMS editors to connect to and make changes to CMS content.  This server is normally only accessible from within the company's internal network.  The one or more "public facing" servers are what the general public connects to.  These "public facing" servers have the CMS edit/admin mode completely disabled.



For example:

Let's say we have our CMS server available onon http://cms.mysite.com (internal network only), and our "public facing" server available on http://www.mysite.com, then...

  • http://cms.mysite.com/episerver would prompt for login, and if the credentials are correct, allow the individual to navigate to CMS edit/admin mode.
  • http://www.mysite.com/episerver would be completely disabled, even if the user managed to steal a CMS editor's credentials.
Some of my Swedish colleagues have told me that this sort of setup is not very common in Sweden.  But I've personally noticed that many of our clients here in the States prefer having a dedicated CMS editor server.  I can't say I blame them.

So how do we harden the "public facing" servers.  It's remarkably easy.  All you have to do is make some tweaks to the Web.config file on the public facing server(s).

Disclaimer: these instructions work for EPiServer CMS 6 R2, I'm not sure about EPiServer CMS 7, but I believe the premise is essentially the same thing.

Web.config changes

The idea here is to modify any <location> element in the Web.config which currently requires WebEditorsWebAdmins or Administrators role membership to access.

For example, the <location> element for "/episerver" access by default looks like:

<location path="episerver">
  <system.web>
    <httpRuntime maxRequestLength="1000000" />
    <pages enableEventValidation="true">
      <controls>
        <add tagPrefix="EPiServerUI" namespace="EPiServer.UI.WebControls" assembly="EPiServer.UI" />
        <add tagPrefix="EPiServerScript" namespace="EPiServer.ClientScript.WebControls" assembly="EPiServer" />
        <add tagPrefix="EPiServerScript" namespace="EPiServer.UI.ClientScript.WebControls" assembly="EPiServer.UI" />
      </controls>
    </pages>
    <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
    <authorization>
      <allow roles="WebEditors, WebAdmins, Administrators" />
      <deny users="*" />
    </authorization>
  </system.web>
  <system.webServer>
    <handlers>
      <clear />
      <add name="webresources" path="WebResource.axd" verb="GET" type="System.Web.Handlers.AssemblyResourceLoader" />
      <add name="PageHandlerFactory-Integrated" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode" responseBufferLimit="4194304" />
      <add name="SimpleHandlerFactory-Integrated" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode" responseBufferLimit="4194304" />
      <add name="WebServiceHandlerFactory-Integrated" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode" responseBufferLimit="4194304" />
      <add name="wildcard" path="*" verb="*" type="EPiServer.Web.StaticFileHandler, EPiServer" />
    </handlers>
  </system.webServer>
</location>

Notice that the <allow> element currently specifies that WebEditors, WebAdmins, and Administrators can access this location.  The <deny> elements tells IIS to deny everyone else.

All we essentially have to do is remove the <allow> element (comment it out) on the public facing servers and this location will be denied to everyone - including CMS editors/admins.  This means even if someone managed to steal the username and password of a CMS editor, they wouldn't be able to login to CMS edit mode unless they were somehow connected to the internal network and knew the URL to the CMS web application instance.

Please note: you can easily use Visual Studio transforms to create a Solution Configuration which automatically removes the <allow> element when publishing to the "public facing" servers.  We'll take a closer look at transforms in my next blog post.

Here we've commented out the <allow> element for the <location path="episerver"> element.

<location path="episerver">
  <system.web>
    <httpRuntime maxRequestLength="1000000" />
    <pages enableEventValidation="true">
      <controls>
        <add tagPrefix="EPiServerUI" namespace="EPiServer.UI.WebControls" assembly="EPiServer.UI" />
        <add tagPrefix="EPiServerScript" namespace="EPiServer.ClientScript.WebControls" assembly="EPiServer" />
        <add tagPrefix="EPiServerScript" namespace="EPiServer.UI.ClientScript.WebControls" assembly="EPiServer.UI" />
      </controls>
    </pages>
    <globalization requestEncoding="utf-8" responseEncoding="utf-8" />
    <authorization>
      <!--<allow roles="WebEditors, WebAdmins, Administrators" />-->
      <deny users="*" />
    </authorization>
  </system.web>
  <system.webServer>
    <handlers>
      <clear />
      <add name="webresources" path="WebResource.axd" verb="GET" type="System.Web.Handlers.AssemblyResourceLoader" />
      <add name="PageHandlerFactory-Integrated" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode" responseBufferLimit="4194304" />
      <add name="SimpleHandlerFactory-Integrated" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode" responseBufferLimit="4194304" />
      <add name="WebServiceHandlerFactory-Integrated" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Services.Protocols.WebServiceHandlerFactory, System.Web.Services, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode" responseBufferLimit="4194304" />
      <add name="wildcard" path="*" verb="*" type="EPiServer.Web.StaticFileHandler, EPiServer" />
    </handlers>
  </system.webServer>
</location>

You should repeat this step for all <location> objects that currently require WebEditors, WebAdmins, or Adminstrators role membership.

Depending on whether or not your using Commerce and/or Composer you might have to make the changes to the <location> elements with the following paths:

  • <location path="episerver">
  • <location path="episerver/CMS/admin" >
  • <location path="WebServices">
  • <location path="Admin/SettingsPlugin">
  • <location path="Admin/SitePlugin">
  • <location path="Edit">
  • <location path="EPiServerCommon">
  • <location path="dropit/plugin/extension/ui/edit">
  • <location path="dropit/plugin/extension/ui/admin">
After doing this, you'll notice one serious and annoying problem...




Assuming someone is able to login using CMS editor credentials, they can still access the EPiServer context menu (for on page editing), even if they cannot get to CMS edit/admin mode.

This is because the <location> elements don't affect access to the context menu.  The context menu is driven by EPiServer ACLs.

I stumbled across the solution on this blog post by Paul Houghton.  It requires building some code which will disable the EPiServer context menus for all page templates and then using appSettings to control whether or not this code should execute.  You could then configure the appSettings in Web.config for the servers where you want to disable the context menu appropriately.

Well appSettings was fine and dandy several years ago, but these days we use project level application settings.  See this post on Stackoverflow for addition information on the differences between appSettings and application settings.

So let's build a boolean application setting for our project in Visual Studio.



Now we can add some code in PageBase.cs (which all of our EPiServer templates inherit from) to override the onInit() page life cycle method.  This code checks the application settings value and determines if it should enable or disable the EPiServer context menu.

namespace MySite.Core
{
    public abstract class PageBase<T> : TemplatePage<T> where T : PageTypeBase
    {
        protected override void OnInit(System.EventArgs e)
        {
            if (ContextMenu != null && !Settings.Default.EnableEPiContextMenu)
            {
                ContextMenu.IsMenuEnabled = false;
            }

            base.OnInit(e);
        }
    }
}

The great part about application settings is that the values are compiled into the DLL, but can be overriden via the Web.config.  If you don't supply a value in Web.config, the compiled in value is used.  Pretty cool huh?

So now all we have to do is override the "True" value for our EnableEPiContextMenu in the Web.config on our public facing servers.

<applicationSettings>
  <MySite.Core.Properties.Settings>
    <setting name="EnableEPiContextMenu" serializeAs="String">
      <value>False</value>
    </setting>
  </MySite.Core.Properties.Settings>
</applicationSettings>

Extra steps for sites that don't require login functionality

If your site literally does not require any sort of login functionality for the general public you can further secure your "public facing" severs by disabling the login page completely.  You would keep the login page for the CMS server so that your CMS editors can login.

If you go this route, a person from the general public going to http://www.mysite.com/episerver would get a 404.  This is because:

  1. IIS determines the user is going to a location path that requires login.
  2. IIS tries to respond with the login page defined in the <forms> element in Web.config.
  3. IIS can't find the login page and therefore returns a 404.
If you are using the standard EPiServer login page, you can comment out this line in episerver.config.  This disables the virtual path to "~/Util" where the EPiServer login page is stored.

<virtualPath customFileSummary="~/FileSummary.config">
    <providers>
        ... more ...    
        
          
        <add name="App_Themes_Default" virtualPath="~/App_Themes/Default/"
physicalPath="C:\Program Files (x86)\EPiServer\CMS\6.1.379.0\application\App_Themes\Default"
type="EPiServer.Web.Hosting.VirtualPathNonUnifiedProvider,EPiServer" />
            
        <add name="UI" virtualPath="~/episerver/CMS/"
physicalPath="C:\Program Files (x86)\EPiServer\CMS\6.1.379.0\application\UI\CMS"
type="EPiServer.Web.Hosting.VirtualPathNonUnifiedProvider,EPiServer" />
            
        <!--<add name="UtilFiles" virtualPath="~/Util/"
physicalPath="C:\Program Files (x86)\EPiServer\CMS\6.1.379.0\application\util"
type="EPiServer.Web.Hosting.VirtualPathNonUnifiedProvider,EPiServer" />-->

        ... more ...

    </providers>
</virtualPath>

If you are using a custom login page, just remove it from the build you publish to your "public" facing servers.

That about does it folks.  Tune in next time for how to use Visual Studio transforms to easily customize Visual Studio publish configurations.  This allows you to make configuration changes automatically when publishing builds of your web application to different servers: DEV, TEST, CMS, and PROD.

Thanks!

Rob

Update: As others have pointed out, another approach you can use is to remove the relevant virtual paths in episerver.config.  This approach will return a 404 when trying to access a resource that you don't want the general public to have access to.  This is because IIS literally can't find the resources (you disconnect the virtual link that points to the C:\Program Files\ directory on the file system).

I like the <location> element approach I outlined above works directly with IIS security, and I find it very simple to implement because it's easy to identify which <location> elements to modify.  But this approach is "closer to the metal" in that a malicious individual literally is unable to access the appropriate resources from the file system.

To implement the episerver.config virtual path approach, simply comment out the relevant virtual paths in episerver.config.

<!-- These virtual paths are commented out on 'public facing' server
to prevent access to CMS edit/admin mode

<add name="App_Themes_Default" virtualPath="~/App_Themes/Default/"
physicalPath="C:\Program Files (x86)\EPiServer\CMS\6.1.379.0\application\App_Themes\Default"
type="EPiServer.Web.Hosting.VirtualPathNonUnifiedProvider,EPiServer" />

<add name="UI" virtualPath="~/episerver/CMS/"
physicalPath="C:\Program Files (x86)\EPiServer\CMS\6.1.379.0\application\UI\CMS"
type="EPiServer.Web.Hosting.VirtualPathNonUnifiedProvider,EPiServer" />

<add name="UtilFiles" virtualPath="~/Util/"
physicalPath="C:\Program Files (x86)\EPiServer\CMS\6.1.379.0\application\util"
type="EPiServer.Web.Hosting.VirtualPathNonUnifiedProvider,EPiServer" />

<add name="WebServiceFiles" virtualPath="~/WebServices/"
physicalPath="C:\Program Files (x86)\EPiServer\CMS\6.1.379.0\application\webservices"
type="EPiServer.Web.Hosting.VirtualPathNonUnifiedProvider,EPiServer" />

<add name="EPiServerCMS" virtualPath="~/episerver/CMS"
physicalPath="C:\Program Files (x86)\EPiServer\CMS\6.1.379.0\application\UI\EPiServer\CMS"
type="EPiServer.Web.Hosting.VirtualPathNonUnifiedProvider,EPiServer" />

<add name="EPiServerShell" virtualPath="~/episerver/Shell"
physicalPath="C:\Program Files (x86)\EPiServer\Framework\6.2.267.1\Application\UI"
type="EPiServer.Web.Hosting.VirtualPathNonUnifiedProvider,EPiServer" />

<add name="EPiServerUrlMappingVPP" virtualName="ExtensionMapping" virtualPath="~/episerver/CMS/"
bypassAccessCheck="false" showInFileManager="false" type="EPiServer.Web.Hosting.VirtualPathMappedProvider,EPiServer" />

<add name="EPiServerCommon" virtualPath="~/EPiServerCommon"
physicalPath="C:\Program Files (x86)\EPiServer\CommonFramework\4.1.517.380\Application\EPiServerCommon"
type="EPiServer.Web.Hosting.VirtualPathNonUnifiedProvider,EPiServer" />
-->