How CDN can effect personalisation

Without going into detailed benefits of CDN, generally CDNs are used to deliver the contents from fastest and closest available server.  In Episerver Digital Experience Cloud services, CDN has its own URL pointing to the original URL. The visitor will navigate to something like “www.customer.com”. The request will go to the CDN, which in turn goes to the origin URL for non-cached data. The request will return to the CDN, which will cache the content.  

Personalisation based on Geolocation will be effected as IP detection services will receive edge server’s IP. In a CDN setup, requests to the web server often come from an edge server and not from the actual client; therefore the HttpContext.Request.UserHostAddress property reflects the edge server’s IP address rather than the connecting client’s. This can be corrected by configuring the header with true IP. 
Add following settings in AppSettings
key=”episerver:ClientIPAddressHeader” value=”True-Client-IP”
*header name will be based on the header sent from the CDN(the header name differs between CDNs)

How to render SVG in edit mode

Self note: SVG is a smart media format that enables us to use same image in different sizes without compromising on quality and performance. EPiServer supports SVGs but images will not display in editor mode while using the IMG tag, as media urls are updated with version details. e.g. “globalassets/160-835st_bilok_2_screw_straight8mm_x_35mm.svg” will change as  “/episerver/CMS/Content/globalassets/en/160-835st_bilok_2_screw_straight8mm_x_35mm.svg,,1823?epieditmode=False&visitorgroupsByID=undefined”. EpiServer will resolve urls for media in this way in Edit and Preview mode. In result svg will not be shown in editor mode. To display the SVG in edit mode, we will be required to resolve url in Default mode, this can be done by calling an overload of the GetUrl-method of the UrlResolver:

UrlResolver.Current.GetUrl(svgContent, language, new VirtualPathArguments() { ContextMode = ContextMode.Default })

Walk through KPI

A key performance indicator (KPI) records when a visitor on a website performs a desired action, such as clicking on an add button, or runs a piece of java script. A custom KPIs can be creating by implementing IKPI interface, to use in Episerver A/B testing or in any other package that relies on creating instance-based goal objects.

An example Implementation can be found on GIST

Helpful links:
http://world.episerver.com/documentation/developer-guides/CMS/key-performance-indicators-kpis/
https://www.david-tec.com/2016/11/creating-a-custom-conversion-goal-with-episerver-ab-testing/

POC custom pricing provider works

In most ecommerce websites, prices comes from some third system and we import the prices into EPiServer Commerce along with products and variants data, but this is not the case all the time. In some scenarios pricing are quite complex and have to decide at run time or require to retrieve from some web services. A custom pricing provider can be built to support these kind of scenarios. we are require to implement IPriceService for read only prices and IPriceDetailService for Editing prices. We will be require to register these service in structure map e.g.
services.AddSingleton< IPriceService, CustomPriceService >();
Find the POC on GIST

Custom Line Item Validator

Amazon offers AddOn products that can be bough with some other product only. Addon products must be removed from basket if added without the parent product. This type of validation can be done easily by implementing ILineItemValidotr interface.

You can find a test implementation of custom Line Item Validator on Git.

You will require to register new custom validation class implicitly into your container.
It will be helpful if in future versions a generic type can be used rather ValidationIssue Enum in Validate method.

Handle Exceptions in Find

If it’s repetitive, it can be automated. Think about the following requirements. Have you ever hoped there would be a better way to implement them?

  • INotifyPropertyChanged
  • Undo/redo
  • Code contracts (preconditions)
  • Logging
  • Transaction handling
  • Exception handling
  • Thread dispatching
  • Thread synchronization
  • Immutable
  • Authorization
  • Audit
  • Caching
Generally we will be doing this

        private SearchResults<DummyObject> GetResults()
        {
            try
            {
                var query = client.Search<DummyObject>();
                var results = query.Take(10).StaticallyCacheFor(TimeSpan.FromMinutes(5)).GetResult();
                return results;
            }
            catch (ServiceException exception)
            {
                //Blah blah
            }
            catch (ClientException exception)
            {
                //Blah blah
            }
        }

There are few issues in above code 

  • Exception code will be repititive and will expand the class after some time.
  • Mixing code in business logic.
  • More than one responsibilities in one object.

There are many ways to deal with this but here PostSharp is my friend.

//Add Attribute
[HandleException(“Exception In Find”)]
private SearchResults<DummyObject> GetResults()
{
       var query = client.Search<DummyObject>();
       var results = query.Take(10).StaticallyCacheFor(TimeSpan.FromMinutes(5)).GetResult();
       return results;
}
//Create an Aspect
[Serializable]
public class HandleExceptionAttribute : OnExceptionAspect
{
     private string message;
    public HandleExceptionAttribute(string message)
    {
        this.message = message;
    }
    public override void OnException(MethodExecutionArgs args)
    {
        args.FlowBehavior = FlowBehavior.Continue;
        string errorMessage = string.Empty;
        switch (args.Exception.GetType().Name)
        {
            case “ServiceException”:
                errorMessage = “Service is down, or if there is any other communication problem.”;
                break;
            case “ClientException”:
                errorMessage = “Query contains errors that is found at runtime”;
                break;
        }
        Console.WriteLine(string.Format(“{0} – {1}”, message, errorMessage));
     }
}

Useful Nuget commands

Having the little knowledge of Nuget Commands is important if your company is thinking to adopt EPiServer Continuous Release Process.

In Visual Studio Click  Tools>Nuget Package Manager>Package Manage Settings, Select from Options, Package manager>Package Sources.
Click + Button and add an entry with
Name: EpiServer packages
Source: http://nuget.episerver.com/feed/packages.svc/

After these setting you are ready to use EPiserver Nugets. Nuget Packages can be installed from ‘Package manager Console’ or ‘Manage Nuget Packages For Solution’ window.

Here are few useful nuget commands

To extract the SQL schema Changes Find the full article (http://robertlinde.se/post/episerver-sql-scripts-and-continuous-integration-with-octopus-deploy)
Export-EPiUpdates

To update database after upgrade
update-epidatabase

In order to see the list of available versions of an episerver package you can use a command like this
Get-Package -ListAvailable -Filter EpiServer.Find -AllVersions

To install a specific version of package this command can be used
Install-Package EPiServer.Find -Version 8.2.4.684

To Uninstall a package following command can be used
Uninstall-Package EPiServer.Find -Version 8.2.4.684

Update a particular package in all projects of the current solution to a particular version
Update-Package EPiServer.Find -Version 8.2.4.684

Re-install a particular package
Update-Package EPiServer.Find -reinstall

Re-install all packages
Update-Package -Reinstall

View dependency List
get-package -list EPiServer.Find | select dependencies

Complete list of commands can be find at at http://docs.nuget.org/docs/reference/package-manager-console-powershell-reference

Error handling in IIs 7

Not a new topic but I come across a situation when our offshore team was not able to see the error details. This is reminder if someone forgets that.

In IIS 7.0 The <httpErrors> element allows you to configure custom error messages for your Web site or application. <CustomErrors> won’t work.

Click for further details on httperrors

httpError Elements

EPiServer Error handling

Example Production Enviornment Settings
<httpErrors errorMode=”Custom” existingResponse=”Replace”>
      <error statusCode=”404″ path=”/Page404.html” responseMode=”ExecuteURL”/>
      <error statusCode=”500″ path=”/500-error-page.html” responseMode=”ExecuteURL”/>
</httpErrors>

Developers Environment Settings:
With Settings
<httpErrors errorMode=”Custom” existingResponse=”Replace“></httpErrors>
Error Details on screen will be like this



With Settings
<httpErrors errorMode=”DetailedLocalOnly” existingResponse=”Replace“></httpErrors>
Error Details on screen will be like this

With Settings
<httpErrors errorMode=”DetailedLocalOnly” existingResponse=”Auto“></httpErrors>
Error Details on screen will be like this

Blocks for EPiServer Commerce Catalog Nodes

Can we use Blocks with Catalog nodes? In theory Yes, what can stop you. We had a requirement when CMS editor can add a Carousel Block to Catalog Nodes. But Block Gadget was not available in CMS Catalog Edit Mode. Only available gadgets were Catalog, Media, Latest and Versions. From architecture point of view I was convinced that we can add ContentArea for Catalog Nodes and Blocks can be reused for Catalog Nodes also. I googled the issue and find an answer by Linus. Its simple I want to keep solution as a self note.

Add the following section under your <episerver.shell> section in web.config and the blocks gadget should appear for the commerce view (given that you have not customized your view):<viewManager>
<views>
<add name=”/episerver/commerce/catalog”>
<settings>
<add name=”AddSharedBlocks” transformationType=”Add”
definitionName=”EPiServer.Cms.Shell.UI.Components.SharedBlocksComponent”
plugInArea=”/episerver/commerce/assets/defaultgroup” />
</settings>
</add>
</views>
</viewManager>
Media Data:
[CatalogContentType(GUID = “#”, MetaClassName = “DigitalNode”, DisplayName = “Digital Catalog Node”)]
    [AvailableContentTypes(Include = new Type[] { typeof(BookProduct), typeof(BookVariant) })]
    public class DigitalNode : NodeContent
    {
        /// <summary>
        /// Gets or sets the content area for the category.
        /// </summary>
        [Display(
            Name = “Content Area”,
            Description = “Content area to hold cms contents for category like carousels”,
            GroupName = SystemTabNames.Content)]
        [CultureSpecific]
        [Editable(true)]
        public virtual ContentArea MainContentArea { get; set; }
}
Episerver.dll version was 7.5.394.2 (I am not sure yet it has been fixed or added in next versions or not)