EPiServer Dynamic Content not Rendering on page

After spending like 4hrs trying to find out why a dynamic property was not being loaded properly on a webpage, I finally stumbled upon a website with such an easy solution. Basically we had a custom dynamic property which was supposed to output some data but EPiServer was not rendering the control properly.

In the source code, I expected to find :

<a style=”” href=”/Video/Vimeo/60255727/” class=”trigger-video” data-trackingid=”&lt;a href=”><span></span>
<img src=”/Global/PersonalCover-Screengrab.jpg” alt=”Personal cover” />
</a>

…but here’s what I saw instead:

<div data-classid=”b30218a7-77fc-43dd-a844-81935aa9b35e” data-dynamicclass=”Video Plugin” data-state=”VgBpAGQAZQBvAEkAZAA=&amp;NgAwADIANQA1ADcAMgA3AA==|VAByAGEAYwBrAGkAbgBnAEkAZAA=&amp;PABhACAAaAByAGUAZgA9ACIAIgAgAG8AbgBjAGwAaQBjAGsAPQAiAF8AZwBhAHEALgBwAHUAcwBoACgAWwAnAF8AdAByAGEAYwBrAEUAdgBlAG4AdAAnACwAIAAnAFYAaQBkAGUAbwAnACwAIAAnAFAAbABhAHkAJwAsACAAJwBQAGUAcgBzAG8AbgBhAGwAQwBvAHYAZQByACcAXQApADsAIgA+AFYAaQBkAGUAbwAgAGwAaQBuAGsAIABoAGUAcgBlADwALwBhAD4A|SQBtAGEAZwBlAFUAcgBsAA==&amp;LwBHAGwAbwBiAGEAbAAvAFAAZQByAHMAbwBuAGEAbABDAG8AdgBlAHIALQBTAGMAcgBlAGUAbgBnAHIAYQBiAC4AagBwAGcA|SQBtAGEAZwBlAEEAbAB0AA==&amp;UABlAHIAcwBvAG4AYQBsACAAYwBvAHYAZQByAA==|QQBsAGkAZwBuAFIAaQBnAGgAdAA=&amp;” data-hash=”jpJE7dVU4KCYCarsF+2bNaNENaNdJwG1niTwbyZc7CY=” contentEditable=”false” class=”epi_dc”><div class=”epi_dc_h”><div class=”epi_dc_l”><div class=”epi_dc_title”>Video Plugin</div></div><div class=”epi_dc_t”><a href=”#” class=”epi_dc_editBtn”>.</a><a href=”#” class=”epi_dc_previewBtn”>.</a></div></div></div>

EPiServer was not rendering the control properly but was just outputting the string.

The fix is really easy. All I had to do was change the way the dynamic content is being output in code.

So instead of this:

<%= CurrentPage.MyDynamicContent %> // wrong

I used this:

<EPiServer:Property runat=”server” PropertyName=”MyDynamicContent” />

Note that this is the way to render dynamic content in EPiServer but there’s a way you can force the literal output as well to work.

Going to the gym after 10 years!!!

Honestly, you shouldn’t wait that long but for me it must have been more than 10 years since I last did any kind of exercise. I was quite active before but since I’ve come to the UK, the cold weather has made me a couch potato and it doesn’t help that I work in an office and sit all day long staring at the computer.

Anyway, I thought a decade was quite a long time and something needed to be done. I’m not getting any younger and I’ve started to feel my body is not as flexible and strong as before. So I signed up for a gym membership with Fitness First (1 month just in case, lol). Since it was a short term contract, it’s £62 but if you go for 4 months contract then it’s £52 and your yearly membership, it’s £42. I’d rather pay a bit more expensive but have the option to cancel within 30 days as I’m still not sure of my commitment as I’ve got loads of things going on as well.

Few things I didn’t think  about were joining fee for the club (£20, but they forgot to include that in my bill, yay!), appropriate clothing and footwear when exercising in the gym and parking which fortunately is not far from the club and members get 2hrs free. I’ve also been persuaded to take a personal trainer as well – 4 sessions for £15 instead of  £30, I just thought why not 😀

And on my first day in the gym, the personal trainer was talking to me about posture and correct way to do things which was all good up until he asked me to do 10 press ups. I could hardly manage 4! I still did 10 though but they were not press ups, after 5 they were more like trying to get your body up any way you can using your hand, lol.

We did some bench press as well with little weights, well he thought they were little but I thought he was trying to kill me, haha. Yes, I know, my body is used to laziness and intermittent smoking hasn’t done me any favours too. We got through some rowing, arm curl for bicep and tricep and finished with lunges. I thought he said lunch btw.

By the end of the session (about 1hr) which to me felt like an eternity, my arms and legs were aching. I was glad I survived and I’m sure I’m going to build up the resistance if I persist. I must admit, I always thought I was a handsome guy until I saw myself in a gym mirror which made me looked too skinny. But then again handsomeness is to do with the face, right?

Now I need to plan my diet better because training without proper nutrition is stupid. However I’m planning to become vegetarian as well, so I’m not sure how that’s going to work out.

Learning EPiServer and Extending Its Functionality

So I’ve recently joined this company and they use EPiServer as a base and build custom functionality on top of that. Therefore I was required to learn how the CMS works in order to fulfill my role as a .NET Web Developer.

The very first thing I needed to do was to get a dev version on my local machine.  On Episerver’s website, I downloaded the version we used most in the company (EPiServer CMS 6 R2) and then I launched the installation process. The setup did not go smoothly as it got aborted because it could not create the database. My Windows credentials were not given the right permission on MS SQL Express 2012 (blame the System Administrator!). Anyway, once that got sorted, I installed the Alloy Tech sample website from EPiServer Deployment Centre. However that was just a blank project with just core files, contrary to what I was expected to see. The thing is I was following a tutorial from a blog and it had screenshots of what the website was supposed to look like but the end result for me was completely different. Later I found out the blog was outdated.

Next it was time getting used to Page Types, something that the CMS uses a lot. Once you get an understanding of that, everything else starts to make more sense. Then comes the querying of the CMS, for example, search for a a list of specific page type starting from the homepage. You can achieve this by creating a criteria query or using PageTypeBuilder (PTB), the latter being more strongly typed. Note that PTB is an open source project which needs to be imported in the project before you can use its awesomeness.

So far so good but still a long way before mastering the CMS; the coding is the easy one 🙂

Inspired by pain, driven by will and created with hope

She tells me to get a tattoo of her name but doesn’t realise her name is already engraved on my heart.
She believes it’s all over, however what awaits is still togetherness.
She thinks what was, isn’t anymore, yet what remains, is stronger than before.
She sees what everyone else does, although what truly is stays unbeknown to anyone.
She knows what we have is real, yet doubts what cannot be disputed.
She pretends not to love but her heartbeats betrays her at each moment.
She looks for sincerity but doesn’t see the mirror of my eyes.
She tries not to look back but what lies ahead is the dream we built.
She forgets what she needs but attends to my desires.
She finds my excuses lame yet wishes they are true.
She cries in silence and thinks I don’t see her tears.
She fights her conscience but surrenders to fate.
She awaits my call yet pretends to be busy.
She puts on a fake smille and hopes no one catches her.
She builds a wall with her pride but secretly wishes my love to invade.
She wishes to hold my hand yet is scared of my touch.
She feels my pain but refuses to show empathy.
She knocks on my door yet feels surprised to see me.
She hates thinking about me but secretly cherishes my memories.
She listens to her mind but none to her heart.
She loves me but denies it everytime.
She is all that yet is incomplete without me!

Search Engine Optimisation for Mauritian websites

I actively monitor the SERPs on Google.mu for a lot of keywords and I can tell you that people in Mauritius do not invest in SEO at all. Many websites which occupy the top positions rank purely because of lack of competition. I can confidently say that search engine optimisation in Mauritius is non-existant except for a few people who are in the website creation business (I can count them on my hand btw). It is to be noted that an awful lot of businesses do not have a website in this day and age and they couldn’t care any less. You will sometimes be amazed by those who have an online presence because their websites are just not worth the effort. Take for example a popular furniture and electrical giant like Courts which have a single page website with an image flyer that links to their Facebook page. Customers want to see what products you have and what the prices are, not being forced to visit your fan page to see e-catalogues of your products. What, are you still in the 1990s era?

courts

There’s this driving school which has a website (maybe the only one in this business actually) and although it has some useful webpages with great information, the title of all its webpages is just the name of the driving school itself. Anyone in the search engine optimisation business can tell you the title tag is the single most important bit you need to optimise. However this site ranks for a lot of associated keywords because Google is inferring its quality from the url of the webpage and the content it has as a substitution for not having enough relevant websites to display. What I’m trying to say is due to the lack of info on this subject in the Mauritian context, the website is ranking despite being unoptimised – same as the one eye man is king in the valley of the blind.

We also have some individuals who think they know a lot of SEO and use black hat techniques to accomplish their goals. For example, there was this web design firm which managed to get a number 1 listing for a 2 keyword phrase I’m currently tracking but it was short lived because all the external backlinks came from blog comments on sites where there’s no moderation, which has led to the domains being listed as spam. Now you wouldn’t want to associate yourself with bad domains because you’d be considered a spammer too and that will definitely hurt your rankings. Anyway if you’re after rankings that last (or at least factors which have a strong impact on your rankings), you need to go white hat and invest more into branding.

Doing business online is still very new in Mauritius and now is the time to crush your competitors and set yourself apart and gain that trust which will benefit you so much more in the future. And if you’re planning to do SEO, then do it right through ethical ways or don’t do it at all.

A not so obvious 403 error permission denied in IIS 7.5

What could be worse than having your live website inaccessible for a long time? Yesterday, I went onto live chat with my web host because I couldn’t get something working. I wanted to block an IP address that was causing a lot of errors and 404s on my website. I’ve added an entry in the IP and Domain Restrictions Settings in IIS the day before assuming the web server will block all requests to any pages on my sites. Well the following day, I got a few more email alerts regarding more 404 errors through email and it came from the same IP I have banned.

ip address restrictions

So I talked to someone from the web hosting company but she seemed clueless. I figured out she was a Level 1 customer support and had little knowledge, so I left the chat but I was unaware she would mess things up completely for me. After an hour, when I was checking the real time data on Google Analytics, I was surprised to see no visitors online. This has never happened before and I waited for 5 mins but nothing changed. So I tried to access my website to see if there was a problem and bam, I was greeted with an HTTP Error 403 – Forbidden: Access is denied – You are not authorized to view this page – You do not have permission to view this directory or page using the credentials that you supplied. My heart sank and I tried other domains on the same server but everything was down.

I tried to fix the problem myself but I could not find the root cause of it. I checked whether anonymous access was enabled and whether the IUSR account was working fine. I tried assigning new application pools too but it did not work. I disabled the firewall as well but in vain.

By the time a support ticket was opened and someone fixed the problem, the downtime was just over 2 hours. I hate to think about how many visitors were put off by this and how much money I lost along the way. It was the first time, my sites were offline for such a long time. Anyway the problem was that the stupid lady went into IP Address and Domain Restrictions and turned “Access to unspecified clients” to Deny which caused the 403 problem. By turning this back to allow, the problem was fixed.

feature settings

I did not spot the problem because I did not realise the Feature Settings had more configuration options for the IP Address and Domain Restrictions module. Anyway, I’m glad things are working fine again.

 

Fixing the ASP.NET Chart not displaying problem in MVC

To generate charts on the fly, you can leverage the MsChart feature of ASP.Net and it’s a free component which makes it even more cool. Everything was working fine on my development machine which has Windows 7 and using .net framework 4.0 and IIS 7.5. However when I uploaded the files to the production server, the chart was not rendering on the live website and it took me the whole day yesterday (12 hours straight on) to fix the problem. I’ve been on lots and lots of blogs, forums and other websites trying to find a solution to my problem but I had inadvertently created a bug myself. Since you need at least 2 data points to create a chart, I inserted a line of code which would see if there were at least 2 data points before creating the chart, otherwise to return null and that was my biggest mistake. Since many people have reported problems with their asp.net charts not showing up, I find myself obliged to share my experiencing in getting yours fixed.

Which .net framework are you using?

In .net framework 4.0, the charting library has been included. For the 3.5 version, you may be required to have the following dlls in your bin folder:


using System.Web.UI.DataVisualization;
using System.Web.UI.DataVisualization.Charting;
using System.Drawing;

Remember on your dev machine, sometimes those assemblies are already in the GAC but not necessarily on your production servers. It is also worth mentioning the DataVisualization is located in the System.Web.DataVisualization dll (not the omission of UI in the namespace).

Set privateImages to false in your appSettings

In the web.config appSettings key, you might need to turn off privateImages because it is true by default and if the request is not authorised, the images won’t be displayed.

<add key="ChartImageHandler" value="storage=memory;deleteAfterServicing=true;privateImages=false;timeout=20;"/>

Explicitly define the ChartImg.axd http handlers in your web.config

The code below shows the main sections where the configurations need to be added:

<appSettings>
<add key="ChartImageHandler" value="storage=memory;deleteAfterServicing=true;privateImages=false;timeout=20;"/>
 </appSettings>

 <system.web>
 <compilation debug="true" targetFramework="4.0">
 <assemblies>
 <add assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
 </assemblies>
 </compilation>

 <httpHandlers>
 <add path="ChartImg.axd" verb="GET,HEAD,POST" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false" />
 </httpHandlers>

 <controls>
 <add tagPrefix="asp" namespace="System.Web.UI.DataVisualization.Charting"
 assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
 </controls>
 </system.web>

 <system.webServer>
 <validation validateIntegratedModeConfiguration="false" />
 <handlers>
 <remove name="ChartImageHandler" />
 <add name="ChartImageHandler" preCondition="integratedMode" verb="GET,HEAD,POST" path="ChartImg.axd" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
 </handlers>
 <system.webServer>

Ignore routes to the chart image handler in your MVC

The MVC routing system may be messing up with your chart image handler sometimes. Many people have had success by ignoring the routes to the url where the charts are created, eg:

routes.IgnoreRoute("ChartImg.axd/{*pathInfo}");
routes.IgnoreRoute("{controller}/ChartImg.axd/{*pathInfo}");
routes.IgnoreRoute("{controller}/{action}/ChartImg.axd/{*pathInfo}");

How to use MsChart in your MVC application

In your view, you just need a an image tag with a url to your controller method which generates the chart as follows:

<img src="/chart/generate/1" alt="chart" />

And in your ChartController:

public FileContentResult Generate(int? id)
 {

// Repository.GetData(id);

List<int> gisData = new List<int>();
 gisData.Add(80);
 gisData.Add(50);
 gisData.Add(95);
 gisData.Add(67);
 gisData.Add(88);

var chart = new Chart();
 chart.Width = 800;

var area = new ChartArea();
 area.AxisY.Maximum = 100;
 area.AxisX.Title = "Attempts";
 area.AxisY.Title = "Points";
 chart.ChartAreas.Add(area);

// create and customize your data series.
 var series = new Series();
 int count = 0;
 foreach (int item in gisData)
 {
 count++;
 series.Points.AddXY(count, item);
 }
 series.Font = new Font("Segoe UI", 8.0f, FontStyle.Bold);
 series.ChartType = SeriesChartType.Line;
 series["PieLabelStyle"] = "Outside";

chart.Series.Add(series);

using (MemoryStream ms = new MemoryStream())
 {
 chart.SaveImage(ms, ChartImageFormat.Png);
 ms.Seek(0, SeekOrigin.Begin);
 return File(ms.ToArray(), "image/png", "mycharg.png");
 }
 }

Instead of an ActionResult for the controller, I’m using a FileContentResult. You can also pass in an id which you can use to query your respository (database) for values to use as data points. In my example, I’m just hard coding the values.

Conclusion

It’s been a really long and frustrating day for me but I’m glad I managed to fix my problem which had nothing to do with the problems other people have faced. Hopefully this post is going to help someone and save their time!

Adding the ASP.net Web API to a Web Forms website

The latest version of the MVC framework comes with ASP.NET Web API support and that’s great. But if like me, you’ve got a web forms website where you want to leverage the capabilities of the Microsoft Web Api, then there are some manual things you need to do.

The first question you need to ask yourself is why do you want the Web Api kit in the first place. For me, my main website runs on web form and it’s too much work at the moment to migrate it to MVC. Other new projects are being done in MVC and I need to way to communicate with the new website. For example, I’ve got a central database which stores user details and I need to get information on a particular user by querying the main website through a web service.  You could very well get the same information by querying the database directly but what if you had business logic as well which filters data before it is displayed? For my problem, I needed to get the total points of a particular user by sending off the UserId.

If you right click on your ASP.NET website in Solution Explorer (Visual Studio) and click on “Add New Item”, you can select the “Web API Controller Class” which I’ve renamed as UserController:

user controller

I didn’t need all those things in the controller, so I removed all and now it looks like this:


public class UserController : ApiController
{
 // GET api/<controller>/5
 public int Get(int id)
 {
 ISession session = NHibernateSessionManager.CreateSession();
 User user = new Repository<User>(session).GetById(id);
 NHibernateSessionManager.CloseSession(session);

return user.Points;
 }
}

But before you could actually compile your site, you need to add the following codes to your Global.ascx file:


void Application_Start(object sender, EventArgs e)
 {
 RouteTable.Routes.MapHttpRoute(
 name: "DefaultApi",
 routeTemplate: "api/{controller}/{id}",
 defaults: new { id = System.Web.Http.RouteParameter.Optional }
 );
 }

This means that if your website is http://www.mydomain.com, you will be able to access your web api at http://www.mydomain.com/api and in my case for my controller it would be:

http://www.mydomain.com/api/user/5 where 5 is the UserId of the user I want to retrieve the points for.

It was as simple as this and I couldn’t believe it.

How to call the Web API url in code

In order to consume the web api, you can use the HttpClient class. For example in my MVC project, I added the following method:


int _points;

public void GetUserPoints(int userId)
 {
 try
 {
 HttpClient client = new HttpClient();
 client.BaseAddress = new Uri(System.Configuration.ConfigurationManager.AppSettings["ApiUrl"]);

client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

HttpResponseMessage response = client.GetAsync(String.Concat("user/", userId)).Result; // Blocking call!
 if (response.IsSuccessStatusCode)
 {
 // Parse the response body. Blocking!
 _points = response.Content.ReadAsAsync<int>().Result;
 }
 }
 catch (Exception ex)
 {
 _points = 50;
 }
 }

You’ll need the following namespaces for it to work:

  • using System.Net.Http;
  • using System.Net.Http.Headers;

Problem getting the Web Api to work on the live server

After everything was tested, I uploaded the new asp.net website which contained my web api interface onto my Windows 2008 box and I was horrified when it threw an error. It was something to do with a missing dll. It happened because the DLL was not found in the GAC while on my local machine that was the case. There are many ways to solve the problem but for me the easier thing was to install the MVC 4 framework on the Windows server to rectify the problem. And that worked!

Error 404 for woff file extension

On one of my website, I was using a special font, the Web Open Font Format (.woff) and while all was working fine in all browsers, I noticed Google Chrome was returning a 404 HTTP Status Code. This meant that it was not able to find the file. I looked into the path given by the style sheet and there it was. So no problem there but what was actually causing the error?

It was my server not knowing what to do with this extension. I was running IIS7.5 and it was not configured to process .woff files. Therefore you either need to add this MIME type to your server by specifying application/x-font-woff to be used for that extension.

woff to iis

Or you can just insert the following lines in your web.config file:


<system.webServer>
 <staticContent>
  <mimeMap fileExtension=".woff" mimeType="application/x-font-woff" />
 </staticContent>
</system.webServer>

I opted for the second option (web.config modification) and Chrome stopped complaining about the missing .woff files.

Fixing Adsense stats not showing up in Google Analytics

I used to be highly involved in optimising Adsense on my sites but when Google Panda struck, that was the last thing on my mind. Before I was getting an increasing amount of visitors every month and there was a steady income coming in but since April 2011, things have changed. I’m not going into the details of this  but a week ago, I decided I must find out what webpages were earning me the most on my sites.

My Adsense account has always been linked to my Analytics account since that functionality was made available but for some reason, only my main domain was being reported in. I double checked my settings in both Adsense & Analytics and they were correct. So I was confused. The report showed only partial earnings and when I investigated, I found statistics for one sub domain was missing.

It was then that I realised the problem was due to a modification I made to my GA code when I wanted to track multiple sub domains with the same code. This is the extra line I had:

_gaq.push([‘_setDomainName’, ‘mydomain.com’]);

To rectify the problem, I had to add the following line to my adsense code:

google_analytics_domain_name=”mydomain.com”;

Therefore your adsense block will look like this:


<script type="text/javascript"><!--
google_analytics_domain_name="mydomain.com";
google_ad_client = "ca-pub-123456789";
/* Custom Adsense Unit */
google_ad_slot = "1000000";
google_ad_width = 336;
google_ad_height = 280;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>

Analytics is now displaying the proper stats for Adsense and I can now see which URLs are bringing in the more clicks and how much the clicks are worth. This will help me optimise these webpages fully and also give me the right insights to monetise other pages of my site.

Note that the Adsense programme does not allow you to modify the ad codes. Therefore you might need to have a separate javascript call as follows:

<script type=”text/javascript”>
google_analytics_domain_name=”mydomain.com”;
</script>