In EPiServer 4.61, you can handle the event for deleting a page and moving it. However, the event for putting a page in the recycle bin is not EPDataFactory.DeletingPage. No, it’s EPDataFactory.MovingPage… since you’re moving it to the bin. When you empty the bin you delete it. It totally makes sense from a developer perspective, but from a human language point of view? Compare it to deleting stuff in Windows.

If you have to keep stuff like that in your head, bugs may occur. I hope you learn from my failure to remember that, it cost me 30 minutes today.

As I stated in the last post, I’m toying around a bit with Subkismet. It’s a great little tool for keeping comment spam at bay, which is a big problem at the EPiServer site I’m currently working on.

It’s also the first open source code that I’ve ever looked into, developed by Phil Haack et al. You can find out more at the project’s CodePlex site. It’s great fun to see how other people use unit testing, inheritance and so on, and a good way of learning more about your own programming style.

I found that the code didn’t do exactly what I wanted to, so I changed it a little, et voilà, I had a visible captcha ready after a few hours. Open source (“or as Microsoft pronounce it: ‘Open Sores’” – quote by Andy Hunt) is a beautiful thing sometimes.

EPiServer and performance

November 30, 2007

I’m currently working on a large (1000+ subsites) EPiServer project and we had some really nasty issues with performance due to a design flaw. Let me just put it like this: If you’re ever thinking about using many dynamic properties on a large site, DON’T! It has been said before, but needs to be repeated.

The situation has allegedly improved quite a bit in EPiServer CMS (5) but in the 4.XX versions, whenever you delete/move/copy a page the cache is emptied and the entire dynamic properties tree has to be reloaded from the database. Which, in our case, took 30 – 60 seconds and no one was able to use the site for that duration.

The solution was to build a plug-in that iterated through the entire site and moved the dynamic properties to pages instead, e.g. start pages. Then we replaced all the calls to dynamic properties with calls to the start pages’ properties, leaving us with only references to the start pages as “dynaprops” (cool word, eh? I made it up myself). Now every time someone deletes a page, the database roundtrip takes 1 second, not 1 minute.

I hope this can prevent anyone from making the same mistake.

I’m currently working on website which is supposed to be able to manage many thousands of users at the same time. But we’re struggling with the performance. So I’ve found some quite useful tools for this:

  1. dotTrace is a profiler for .NET code. A great little tool for finding out what parts of your code take the most time/resources. It’s kinda expensive though.
  2. WebLOAD is an open source load testing solution for internet apps. I like it a lot, even though the documentation is a bit sparse and I’m not quite sure how to interpret all the data I get when testing my sites.

Apart from that, I’ve learned one important lesson when it comes to EPiServer and performance: do not use a lot of dynamic properties for large sites. They tend to suck the life out of the database server, we’ve found stored procedures that take 30-60 seconds just to get all the dynamic properties. Instead we’re going to make them ordinary page properties and push them downwards in the hierarchy.

I’ve been struggling for a while with the installation of an EPiServer site. There’s always something going wrong when installing them it seems. I installed a blank 4.61/ASP.NET 1.1 site and then replaced some of the content with the files from the source control repository, since the whole site wasn’t in the source control system, only the files that had changed.

However, this led me to the following error after having compiled the site for the first time: When trying to open it, my browser just shouted:

“CS1595: ‘development.Global’ is defined in multiple places; using definition from ‘c:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET Files\root\588a0258\4318cd2f\assembly\dl2\af592e75\ 60d0d532_03adc701\EPiServerSample.DLL’”

Okay, so I googled that error. The Microsoft knowledge base article didn’t seem to apply to me at all, instead I found the solution in the Velocity Reviews Forum, where this bloke Alvin Bruney suggests that if there are copies of the same assembly floating around you should:

“delete all these assemblies every where you find them on your hard drive, flush iis temporary files, then rebuild that particular assembly”

So that made my head snap back into it’s position: The EPiServerSample.DLL isn’t even supposed to be there, we’re not using it. So I just deleted it, and then emptied the C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET Files\ folder and re-built the solution. Now there’s only one development.Global, in my real assembly.

Another example of how a tiny, simple problem can delay my work by some hours.

Today the first big problem of making my MS VPCs VMware virtual machines showed its ugly mug. VMware changed the machine’s MAC address, thus making the MAC-restricted EPiServer license invalid. I tried changing the MAC address to the old one in the .vmx-file, but it seems that VMware only supports addresses in a certain range. So now I have to order a new EPiServer license.

Apart from that, VMware Player today gave me my first blue screen on XP ever. Unless you count that one time that my laptop was next to a drum kit (don’t ask), and the drummer’s bass kicking vibrations caused the computer to blue out on me. Also I find it annoying that once you grab control of the mouse and keyboard in the virtual machine, you have to press Ctrl+Alt to return to the host system. In Virtual PC you don’t have to do that.

Apart from that, VMware is FAAAAST. Just saving the state and then recovering it is so smooth as compared to VPC.

I haven’t got much to do right now, except for some really small and easy EPiServer thingees. This is one of them:

The customer wanted to allow the web editors to add javascript in the Edit Mode that was then included in the <head> of the page. Easy to do.

1. Add the following code to the header.ascx file:
<%=GetJavaScript()%>

2. Then put the following method in the code-behind file:
protected string GetJavaScript()
{
if(CurrentPage.Property.Exists("Javascript"))
{
return CurrentPage.Property["Javascript"].ToString();
}
else
{
return String.Empty;
}
}

3. Add an XHTML property called “Javascript” to any pages where you wish to have javascript.

4. Write/paste the javascript in the text box for this property. However, make sure that you paste it in the HTML edit mode, not ordinary text mode. Otherwise EPiServer will just reformat your javascript to html, which isn’t pretty.

Simple problem, simple solution. But I thought I’d share it anyway.

Today when I tried to enable globalization in the admin mode at the production server, I ran into a tiny wall. EPiServer told me that
Access to the path "C:\Inetpub\EPiServer\web.config" is denied.

This lead to some funny behaviour, since the globalization was only enabled for one cache period and then it got disabled again. Very natural, since the setting wasn’t actually saved. What to do?

Just go to the web.config file in explorer, and give the user IIS_WPG rights to write to that file. Now you can save the settings like there’s no tomorrow!

I recently installed EPiServer on my XP computer, which is cumbersome to say the least. For example, when you choose an existing SQL account instead of creating a new one, the installer tells you that “the account already exists” and throws an exception. Duh!

Well, due to many attempts at installing EPiServer, my IIS was crowded with duplicate EPi sites… and I couldn’t find an easy way of deleting them. EDIT: I tried deleting them in EPiServer Manager, but for some reason that didn’t work.

The answer is two things:

1. Download the Microsoft Metabase Editor, and install it. Open up and go to the W3SVC in the LM branch. There you see different numbers for each of your sites. Remember what numbers correspond to the site you want to remove (the name is usually visible in the ServerComment key).

2. Open up the good old cmd.exe, change directory to C:\inetpub\AdminScripts (or wherever your inetpub is) and type the following:

C:\inetpub\AdminScripts>adsutil.vb delete W3SVC/X

where X is the number for the site that you noted from the metabase.

Done and done!

I stumbled upon the aforementioned error after making some changes in my default.aspx code.

The error message didn’t help a lot, but because of Eran Sandler’s blog Advanced .NET Debugging I managed to sort it out.

Because some variables had the same names in the default.aspx and the default.aspx.cs, but the casing was different, the stuff added in the default.aspx.designer.cs file created errors. Either you can remove the lines added in the designer file or do as I did: rename the error generating variable names (thru refactoring of course ;) ) so that more than the casing differs.

And to Eran for finding this error (and/or possible bug): respect.