EPiServer

You are currently browsing articles tagged EPiServer.

image I recently got the question how to fix the incorrect alphabetic sorting of child pages in EPiServer. It is usually Scandinavian users complaining that Å, Ä and Ö are sorted together with A and O instead of being at the end of the list.

Sort order: Alphabetical

When you specify the sort order of child pages your selection is stored in the database (tblPage.PeerOrderRule) and is shared for all language branches.

When you use GetChildren() it calls a stored procedure called netPageLinkList that returns the children ordered differently depending on the selection. Sorting is done in the database.

Easy Solution To Child Page Sort Order in EPiServer

1) Easiest way to fix sorting is to change the Collation order of the Name column in the tblPageLanguage table.

image 

different sort order depending on the current culture

The easy solution only allows one common sort order for the entire database and that might not be good enough for multi lingual sites.

2) You can solve this for the whole site by hooking the event DataFactory.FinishedLoadingChildren and resorting the pages. Remember that this event is called every time you call GetChildren() and the result is not cached.

3) Another way is to solve it locally is to use the FilterSort class on you PageDataCollection or setting the SortOrder property on you PageList.

Tags: , , , , , , , ,

I got a support question on this Exception today. First thought is that the ip-address was misstyped or the wrong license.config file was used but ipconfig /all and the IPRestiriction tag in license.config matched!

How does EPiServer validate the ip-address?

The code to check is quite simple. It is using the DNS service to lookup the name of the computer and then lookup all ip-addresses for that computer name.

foreach (IPAddress address in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
    if (!IPAddress.IsLoopback(address) && this._ip.Equals(address))
    {
        this._isValid = true;
    }
}

Troubleshooting License Exception  

A quick test is to add a small debug.aspx file to find out what values are returned.

<%@ Page Language="C#" AutoEventWireup="true"  %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
 ">
<script runat="server">

    protected void Button1_Click(object sender, EventArgs e)
    {
        foreach (System.Net.IPAddress address in System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList)
        {
            ListBox1.Items.Add(address.ToString()+ "-" + System.Net.IPAddress.IsLoopback(address).ToString());
        }
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml
 " >
<head runat="server"><title></title></head>
<body>
    <form id="form1" runat="server">
    <h1>Check IP-addresses</h1>
    <p>Current host name: <%= System.Net.Dns.GetHostName() %></p>
    <div>
        <asp:ListBox ID="ListBox1" runat="server"></asp:ListBox>
        <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Test" />
    </div>
    </form>
</body>
</html>

Resolution to LicenseException in this case

Running the test aboved showed us that the IP-address returned was the loopback address 127.0.0.1 instead of the computers ip-address.

Since this setup is an enterprise site with a lot of diffrent host names pointing to diffrent start pages the local hosts-file (at C:\Windows\System32\drivers\etc\hosts) was edited and all known host names was added pointing to 127.0.0.1 to make it possible to test. One entry was accidentally added with the machine name and when we removed that line everything started to work!

Tags: , , , ,

image One of our customers required that we limited access to the Advanced Information tab in edit mode for normal editors. A reasonable requirement but how do you enable normal editors to adjust the sort order?

The answer is to move these built-in properties to a new tab.

Where to I hook my Event in EPiServer?

In latest releases of EPiServer CMS you are not allowed to access come parts of EPiServer to early. That is why I hook FirstBeginRequest event on EPiServer InitializationModule during Application_Start in Global.asax. You could also do this in Init() of an HttpModule.

All initialization is then done in that Event handler. We start by loading the target TabDefinition to get the ID then we hook EditPanel.LoadedPage.

EditPanel is the user class implementing EPiServers editor interface and LoadedPage is a static event that is fired every time the editor is shown. A perfect hook to tweak the editor!

Source Code in Global.asax.cs to change tab for properties

protected void Application_Start(Object sender, EventArgs e)
{
    InitializationModule.FirstBeginRequest += InitializationModule_FirstBeginRequest;
}

void InitializationModule_FirstBeginRequest(object sender, EventArgs e)
{
    CreateEventToMovePageOrderPropertyToCustomTab();
}

private int pageOrderTabID;

private void CreateEventToMovePageOrderPropertyToCustomTab()
{
    string pageOrderTabName = WebConfigurationManager.AppSettings["PageOrderTab"];
    var pageOrderTab = TabDefinition.Load(pageOrderTabName);
    if (pageOrderTab!=null)
    {
        pageOrderTabID = pageOrderTab.ID;
        EditPanel.LoadedPage += EditPanel_LoadedPage;
    }
}

void EditPanel_LoadedPage(EditPanel sender, LoadedPageEventArgs e)
{
    e.Page.Property["PageChildOrderRule"].OwnerTab = pageOrderTabID;
    e.Page.Property["PagePeerOrder"].OwnerTab = pageOrderTabID;
}

Settings in web.config

<configuration>
  <appSettings>
    <add key="PageOrderTab"
         value="Sidadministration"/>
  </appSettings>
</configuration>

As usual, drop a comment if you think this is usefull! It is good for my blogging morale. :-)

Tags: , ,

If you allow the visitors of your site to contribute, for example with a simple comment this textbox, you take the risk that a malicious user inject evil code in a comment.

This evil code is then executed in the browser by your sites’ ordinary visitors. Scripts can steals passwords (maybe your own admin account), trick the user to give up other senestive data or download malvare because they trust your site.

This kind of security vulnerability is reffered to as XSS or Cross Site Scripting

Always have input validation and filter you input

A common aproach is to sanitize the data with a whitelisted or blacklisted characters to eliminate dangerous characters before storing or using the data. Another, is to always html encode data when it is rendered.  But it is harder than you think to get it right!

70 ways to write the same character

So you think you are smart and have a string replace or regular expression that removes “<” from the user’s input on your website to be safe? I guess you need to test again… I had too!

Did you know that there is 70 diffrent ways to write the “<” character in html? Read Robert Hansen’s good cheat sheet that lists known XSS attacks to get scared and take the problem serionsly.

Tags: ,

Back from 2 healthy weeks of vacation on Iceland. Time to start blogging again!

This time I want to share a simple but useful snippet of code that sends an email to an EPiServer editor with a link that opens the page for editing in EPiServer Edit Mode.

How to create a go to Edit Mode link and mail it

string baselink = UriSupport.AbsoluteUrlFromUIBySettings("edit/");
string editlink = baselink + "SwitchLanguage.aspx?language=" + page.LanguageBranch +
  "&epUrl=" + Server.UrlEncode(baselink + "default.aspx?id=" + page.PageLink.ToString());
string pageurl = string.Format("<a href=\"{0}\">Edit '{1}'</a>",
  editlink, page.PageName);

Utility.SendEmail("test@inexor.se",

  EPiServerProfile.Current.EmailWithMembershipFallback,
  string.Format("[Moderate] {0}", message),
  string.Format(
  @"<html><body><h1>{0}</h1><p>The page<b>'{1}'</b> must be review and published.</p>" +
  @"<p>Log in to EPiServer Edit Mode and use the following ID in the bottom left search box:<br/>" +
  @"ID: <b>{2}</b></p>" +
  @"<p>Or click on the following link to login and review the page:<br/>{3}</p>",
  new object[] {message, page.PageName, page.PageLink.ID, pageurl}));

Works with unpublished versions of pages

The code above expects a PageData object in the page variable. It handles WorkPageID if you send in a page that is just saved or retrieved through PageVersion class.

Read more about How to work with Unpublished PageData from code in a previous blog post!

As usual, please leave a comment if you find it useful or have something to add. It is good for my blogging morale. :-)

Tags:

« Older entries