Blog about tips & tricks for CMS enhancement

eric.petersson

HostDefinitions in Episerver returns error message: Port must be a parsable integer between 0 and 65535 or wildcard character


If you ever came across this obscure error message in Episerver, you probably have had a look at Erik Henningson's inspiring article for defining HostDefinitions automatically when initializing your Episerver site for different environments.

When dealing with the HostDefinitions themselves in the SiteDefinition declarations as Erik demonstrates in his post, one is ought to think that you may a wildcard hostname as well as a primary host within issues. Hence, the error message "Port must be a parsable integer between 0 and 65535 or wildcard character" pops up if you declare this "wrong".

Below is an example of the solution for this matter. In this example the site is defined to have two typical bindings: wildcard and primary.

private IEnumerable<SiteDefinition> GetSiteDefinitions(string address)
{
    var sites = new List<SiteDefinition>
    {
        new SiteDefinition
        {
            Name = "Alloy Demo",
            SiteUrl = new Uri(address),
            Hosts = new List<HostDefinition>
            {
                new HostDefinition
                {
                    Name = HostDefinition.WildcardHostName,
                    Language = new CultureInfo("en")
                },
                new HostDefinition
                {
                    Name = new Uri(address)?.Host,
                    Type = HostDefinitionType.Primary,
                    Language = new CultureInfo("en")
                }
            }
        }
    };

    return sites;
}

Here, the solution is to declare the second HostDefinition, the primary one to have its name from the Uri namespace and retrieve the Host from that declaration. This will make the initialization of the site work properly and error message will go away.

The in-parameter of address is typically your site's canonical path, such as https://alloy.com/

An example of the entire InitializationModule can be found below:

using System;
using System.Collections.Generic;
using System.Linq;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
using EPiServer.Web;
using System.Globalization;

namespace DV.Domstol.Web.Business.Initialization
{
    /// <summary>
    /// Module for adjusting SiteDefinition settings between Alloy environments
    /// Useful when copying database from Production => Pre-Production => Stage => CI (Development)
    /// </summary>
    [InitializableModule]
    [ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
    public class HostDefinitionsInitialization : IInitializableModule
    {
        public void Initialize(InitializationEngine context)
        {
            var appSettings = ServiceLocator.Current.GetInstance<IAppSettings>();
            var address = appSettings.CanonicalBasePath; // typically https://alloy.com/
            var siteDefinition = GetSiteDefinitions(address);

            MergeSiteDefinitions(siteDefinition);
        }

        /// <summary>
        /// Merge site definitions if they should
        /// alter in configurations between environments.
        /// </summary>
        public void MergeSiteDefinitions(IEnumerable<SiteDefinition> definedSites)
        {
            var siteDefinitionRepository = ServiceLocator.Current.GetInstance<ISiteDefinitionRepository>();
            var existingSites = siteDefinitionRepository.List().ToList();

            foreach (var definition in definedSites)
            {
                var site = existingSites.FirstOrDefault(s => s.Name == definition.Name && s.SiteUrl != definition.SiteUrl);

                if (site == null)
                    continue;

                site = site.CreateWritableClone();
                site.SiteUrl = definition.SiteUrl;
                site.Hosts = definition.Hosts;

                siteDefinitionRepository.Save(site);
            }
        }

        private IEnumerable<SiteDefinition> GetSiteDefinitions(string address)
        {
            var sites = new List<SiteDefinition>
            {
                new SiteDefinition
                {
                    Name = "Alloy",
                    SiteUrl = new Uri(address),
                    Hosts = new List<HostDefinition>
                    {
                        new HostDefinition
                        {
                            Name = HostDefinition.WildcardHostName,
                            Language = new CultureInfo("en")
                        },
                        new HostDefinition
                        {
                            Name = new Uri(address)?.Host,
                            Type = HostDefinitionType.Primary,
                            Language = new CultureInfo("en")
                        }
                    }
                }
            };

            return sites;
        }

        public void Uninitialize(InitializationEngine context)
        {
            // Unused
        }
    }
}

And that's it!

Hope you found this blog post useful - if so, send a click to one of the ads on this blog!