Of Code and Me

Somewhere to write down all the stuff I'm going to forget and then need

Compile Aspx pages at compile time using the AspNetCompiler build task August 18, 2010

Filed under: Asp.Net,Web — Rupert Bates @ 1:20 pm

By default Asp.Net web applications don’t compile aspx files (only the code behind). This means that you can have errors in them which don’t appear until you actually hit the page.

To change this so that your aspx files get compiled along with all the rest of your code do the following:

  • Unload your web app (right click on the project and select ‘Unload Project’)
  • Open the csproj file in a text editor (right click on the project and select ‘Edit myProjectName.csproj’)
  • At the bottom of the file find the comment which says ‘To modify your build process…’ and insert the following after that comment:

<Target Name="AfterBuild">
<AspNetCompiler  VirtualPath="temp"  PhysicalPath="$(ProjectDir)" />
 </Target>

 

Donut caching in asp.net mvc 2 with Html.Action April 8, 2010

Filed under: Asp.Net,C#,MVC,Uncategorized,Web — Rupert Bates @ 11:22 am

[Update – ok, so this officially doesn’t work, which sucks. I’m having a look at alternatives, but at the moment it looks like that is going to be reverting to MVC 1.0]

To do donut caching in Asp.Net Mvc 1.0 required quite a bit of hacking (or at least that was the only way I could get it to work), but with version 2 things get much better because of the addition of the Html.Action method.

As a quick recap, ‘donut caching’ is when you cache the whole of a web page except for small parts within it – the holes in the donut. A classic use for it is pages which have some personalised aspect like a logged in user name but are otherwise identical for all users.

To solve exactly this scenario I used the following code:

A child action called LoggedInUserInfo in my HomeController

        [ChildActionOnly]
        public ActionResult LoggedInUserInfo(HttpContextBase context)
        {
            return View(context);
        }

with a view of the same name:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<HttpContextBase>" %>
<%@ Import Namespace="KableDirect.Service" %>
<%@ Import Namespace="KableDirect.Web.FrontEnd.Models.Shared"%>

    <ul>
        <li>You are logged in as <%= Model.User.Identity.Name %> </li>

        <li><%=Html.ActionLink("My Profile", "Profile", "Account")%></li>

        <%if (Model.User.IsAdmin()){%>
        <li><a href="<%= RouteHelper.GetAdminUrl(Model)%>">Admin</a></li>
        <%}%>
        <li><%=Html.ActionLink("Logout", "Logoff", "Account")%></li>
    </ul>

I also have the following HtmlHelper method to make calling the asp.net WriteSubstitution() method easier:

    public delegate string MvcCacheCallback(HttpContextBase context);
    public static class CacheHelper
    {
        public static object Substitute(this HtmlHelper html, MvcCacheCallback cb)
        {
            html.ViewContext.HttpContext.Response.WriteSubstitution(c => cb(new HttpContextWrapper(c)));
            return null;
        }
    }

Now I can call my child action within my MasterPage using Html.Action as follows:

<%=  Html.Substitute(context => Html.Action("LoggedInUserInfo", "Home", new {context}).ToString()) %>

It is important that your action takes the context as a parameter or it will only be called once the first time the page is hit and then get cached along with everything else.
It is also important that you have a route in your route table that will catch the {controller}/{action} url pattern. See this post for more details.

Phill Haack now has a warning on his site about problems with donut caching in Asp.Net Mvc 2, but this has worked fine for me, I’ll update here if I find scenarios where this doesn’t work.

There is a good introduction to Html.Action here.

 

Error: No route in the route table matches the supplied values when using Html.Action or Html.RenderAction in Asp.Net MVC April 6, 2010

Filed under: Asp.Net,Error,Web — Rupert Bates @ 4:20 pm

I ran across this error today when using the new Html.Action:

System.InvalidOperationException: No route in the route table matches the supplied values.

It turns out that Action and RenderAction require there to be a default route to catch the {controller}/{action} pattern.

So adding this into the RegisterRoutes method fixed the problem:

routes.MapRoute(
                "DefaultAction",
                "{controller}/{action}",
                new
                {
                    controller = "Home",
                    action = "Index"
                }
                );
 

Format a string in RFC 2822 format for use with Http headers in c# March 17, 2010

Filed under: Asp.Net,C#,Coding,Web — Rupert Bates @ 11:45 am
var lastModified = AppStart.ToString("ddd, dd MMM yyyy hh:mm:ss ") + "GMT"; //note the hard coded GMT, there doesn't seem to be any other way to get this

Custom Date and Time Format Strings on MSDN
Standard Date and Time Format Strings on MSDN

 

An extended Html.Encode function for the Asp.Net Mvc HtmlHelper February 12, 2010

Filed under: Asp.Net,C#,MVC — Rupert Bates @ 2:52 pm

The built in Asp.Net Html encoding function misses out a large number of extended characters (including apostrophes). This extension method for the HtmlHelper class does a much more thorough job:

using System.Collections.Generic;
using System.Web.Mvc;

namespace KableDirect.Web.FrontEnd.Helpers
{
    public static class HtmlHelperExtensions
    {
        #region The List of replacements

        public static readonly Dictionary<string, string> Replacements = new Dictionary<string, string>
                                                                             {
                                                                                 {"–", "&#8211;"},
                                                                                 {"—", "&#8212;"},
                                                                                 {"‘", "&#8216;"},
                                                                                 {"’", "&#8217;"},
                                                                                 {"‚", "&#8218;"},
                                                                                 {"“", "&#8220;"},
                                                                                 {"”", "&#8221;"},
                                                                                 {"„", "&#8222;"},
                                                                                 {"†", "&#8224;"},
                                                                                 {"‡", "&#8225;"},
                                                                                 {"•", "&#8226;"},
                                                                                 {"…", "&#8230;"},
                                                                                 {"‰", "&#8240;"},
                                                                                 {"€", "&#8364;"},
                                                                                 {"™", "&#8482;"},
                                                                                 {"'", "&#39;"},
                                                                                 {"ą", "&#261;"},
                                                                                 {"Ą", "&#260;"},
                                                                                 {"ę", "&#281;"},
                                                                                 {"Ę", "&#280;"},
                                                                                 {"Ā", "&#256;"},
                                                                                 {"ā", "&#257;"},
                                                                                 {"Ă", "&#258;"},
                                                                                 {"ă", "&#259;"},
                                                                                 {"Ǟ", "&#478;"},
                                                                                 {"ǟ", "&#479;"},
                                                                                 {"Ǻ", "&#506;"},
                                                                                 {"ǻ", "&#507;"},
                                                                                 {"Ǽ", "&#508;"},
                                                                                 {"ǽ", "&#509;"},
                                                                                 {"Ḃ", "&#7682;"},
                                                                                 {"ḃ", "&#7683;"},
                                                                                 {"Ć", "&#262;"},
                                                                                 {"ć", "&#263;"},
                                                                                 {"Č", "&#268;"},
                                                                                 {"č", "&#269;"},
                                                                                 {"Ĉ", "&#264;"},
                                                                                 {"ĉ", "&#265;"},
                                                                                 {"Ċ", "&#266;"},
                                                                                 {"ċ", "&#267;"},
                                                                                 {"Ḑ", "&#7696;"},
                                                                                 {"ḑ", "&#7697;"},
                                                                                 {"Ď", "&#270;"},
                                                                                 {"ď", "&#271;"},
                                                                                 {"Ḋ", "&#7690;"},
                                                                                 {"ḋ", "&#7691;"},
                                                                                 {"Đ", "&#272;"},
                                                                                 {"đ", "&#273;"},
                                                                                 {"DZ", "&#497;"},
                                                                                 {"Dz", "&#498;"},
                                                                                 {"dz", "&#499;"},
                                                                                 {"DŽ", "&#452;"},
                                                                                 {"Dž", "&#453;"},
                                                                                 {"dž", "&#454;"},
                                                                                 {"Ě", "&#282;"},
                                                                                 {"ě", "&#283;"},
                                                                                 {"Ē", "&#274;"},
                                                                                 {"ē", "&#275;"},
                                                                                 {"Ĕ", "&#276;"},
                                                                                 {"ĕ", "&#277;"},
                                                                                 {"Ė", "&#278;"},
                                                                                 {"ė", "&#279;"},
                                                                                 {"Ʒ", "&#439;"},
                                                                                 {"ʒ", "&#658;"},
                                                                                 {"Ǯ", "&#494;"},
                                                                                 {"ǯ", "&#495;"},
                                                                                 {"Ḟ", "&#7710;"},
                                                                                 {"ḟ", "&#7711;"},
                                                                                 {"ƒ", "&#402;"},
                                                                                 {"ff", "&#64256;"},
                                                                                 {"fi", "&#64257;"},
                                                                                 {"fl", "&#64258;"},
                                                                                 {"ffi", "&#64259;"},
                                                                                 {"ffl", "&#64260;"},
                                                                                 {"ſt", "&#64261;"},
                                                                                 {"Ǵ", "&#500;"},
                                                                                 {"ǵ", "&#501;"},
                                                                                 {"Ģ", "&#290;"},
                                                                                 {"ģ", "&#291;"},
                                                                                 {"Ǧ", "&#486;"},
                                                                                 {"ǧ", "&#487;"},
                                                                                 {"Ĝ", "&#284;"},
                                                                                 {"ĝ", "&#285;"},
                                                                                 {"Ğ", "&#286;"},
                                                                                 {"ğ", "&#287;"},
                                                                                 {"Ġ", "&#288;"},
                                                                                 {"ġ", "&#289;"},
                                                                                 {"Ǥ", "&#484;"},
                                                                                 {"ǥ", "&#485;"},
                                                                                 {"Ĥ", "&#292;"},
                                                                                 {"ĥ", "&#293;"},
                                                                                 {"Ħ", "&#294;"},
                                                                                 {"ħ", "&#295;"},
                                                                                 {"Ĩ", "&#296;"},
                                                                                 {"ĩ", "&#297;"},
                                                                                 {"Ī", "&#298;"},
                                                                                 {"ī", "&#299;"},
                                                                                 {"Ĭ", "&#300;"},
                                                                                 {"ĭ", "&#301;"},
                                                                                 {"Į", "&#302;"},
                                                                                 {"į", "&#303;"},
                                                                                 {"İ", "&#304;"},
                                                                                 {"ı", "&#305;"},
                                                                                 {"IJ", "&#306;"},
                                                                                 {"ij", "&#307;"},
                                                                                 {"Ĵ", "&#308;"},
                                                                                 {"ĵ", "&#309;"},
                                                                                 {"Ḱ", "&#7728;"},
                                                                                 {"ḱ", "&#7729;"},
                                                                                 {"Ķ", "&#310;"},
                                                                                 {"ķ", "&#311;"},
                                                                                 {"Ǩ", "&#488;"},
                                                                                 {"ǩ", "&#489;"},
                                                                                 {"ĸ", "&#312;"},
                                                                                 {"Ĺ", "&#313;"},
                                                                                 {"ĺ", "&#314;"},
                                                                                 {"Ļ", "&#315;"},
                                                                                 {"ļ", "&#316;"},
                                                                                 {"Ľ", "&#317;"},
                                                                                 {"ľ", "&#318;"},
                                                                                 {"Ŀ", "&#319;"},
                                                                                 {"ŀ", "&#320;"},
                                                                                 {"Ł", "&#321;"},
                                                                                 {"ł", "&#322;"},
                                                                                 {"LJ", "&#455;"},
                                                                                 {"Lj", "&#456;"},
                                                                                 {"lj", "&#457;"},
                                                                                 {"Ṁ", "&#7744;"},
                                                                                 {"ṁ", "&#7745;"},
                                                                                 {"Ń", "&#323;"},
                                                                                 {"ń", "&#324;"},
                                                                                 {"Ņ", "&#325;"},
                                                                                 {"ņ", "&#326;"},
                                                                                 {"Ň", "&#327;"},
                                                                                 {"ň", "&#328;"},
                                                                                 {"ʼn", "&#329;"},
                                                                                 {"Ŋ", "&#330;"},
                                                                                 {"ŋ", "&#331;"},
                                                                                 {"NJ", "&#458;"},
                                                                                 {"Nj", "&#459;"},
                                                                                 {"nj", "&#460;"},
                                                                                 {"Ō", "&#332;"},
                                                                                 {"ō", "&#333;"},
                                                                                 {"Ŏ", "&#334;"},
                                                                                 {"ŏ", "&#335;"},
                                                                                 {"Ő", "&#336;"},
                                                                                 {"ő", "&#337;"},
                                                                                 {"Ǿ", "&#510;"},
                                                                                 {"ǿ", "&#511;"},
                                                                                 {"Œ", "&#338;"},
                                                                                 {"œ", "&#339;"},
                                                                                 {"Ṗ", "&#7766;"},
                                                                                 {"ṗ", "&#7767;"},
                                                                                 {"Ŕ", "&#340;"},
                                                                                 {"ŕ", "&#341;"},
                                                                                 {"Ŗ", "&#342;"},
                                                                                 {"ŗ", "&#343;"},
                                                                                 {"Ř", "&#344;"},
                                                                                 {"ř", "&#345;"},
                                                                                 {"ɼ", "&#636;"},
                                                                                 {"Ś", "&#346;"},
                                                                                 {"ś", "&#347;"},
                                                                                 {"Ş", "&#350;"},
                                                                                 {"ş", "&#351;"},
                                                                                 {"Š", "&#352;"},
                                                                                 {"š", "&#353;"},
                                                                                 {"Ŝ", "&#348;"},
                                                                                 {"ŝ", "&#349;"},
                                                                                 {"Ṡ", "&#7776;"},
                                                                                 {"ṡ", "&#7777;"},
                                                                                 {"ſ", "&#383;"},
                                                                                 {"Ţ", "&#354;"},
                                                                                 {"ţ", "&#355;"},
                                                                                 {"Ť", "&#356;"},
                                                                                 {"ť", "&#357;"},
                                                                                 {"Ṫ", "&#7786;"},
                                                                                 {"ṫ", "&#7787;"},
                                                                                 {"Ŧ", "&#358;"},
                                                                                 {"ŧ", "&#359;"},
                                                                                 {"Ũ", "&#360;"},
                                                                                 {"ũ", "&#361;"},
                                                                                 {"Ů", "&#366;"},
                                                                                 {"ů", "&#367;"},
                                                                                 {"Ū", "&#362;"},
                                                                                 {"ū", "&#363;"},
                                                                                 {"Ŭ", "&#364;"},
                                                                                 {"ŭ", "&#365;"},
                                                                                 {"Ų", "&#370;"},
                                                                                 {"ų", "&#371;"},
                                                                                 {"Ű", "&#368;"},
                                                                                 {"ű", "&#369;"},
                                                                                 {"Ẁ", "&#7808;"},
                                                                                 {"ẁ", "&#7809;"},
                                                                                 {"Ẃ", "&#7810;"},
                                                                                 {"ẃ", "&#7811;"},
                                                                                 {"Ŵ", "&#372;"},
                                                                                 {"ŵ", "&#373;"},
                                                                                 {"Ẅ", "&#7812;"},
                                                                                 {"ẅ", "&#7813;"},
                                                                                 {"Ỳ", "&#7922;"},
                                                                                 {"ỳ", "&#7923;"},
                                                                                 {"Ŷ", "&#374;"},
                                                                                 {"ŷ", "&#375;"},
                                                                                 {"Ÿ", "&#376;"},
                                                                                 {"Ź", "&#377;"},
                                                                                 {"ź", "&#378;"},
                                                                                 {"Ž", "&#381;"},
                                                                                 {"ž", "&#382;"},
                                                                                 {"Ż", "&#379;"},
                                                                                 {"ż", "&#380;"}
                                                                             };
        #endregion

        /// <summary>
        /// A fuller html encoding than the built in method, will encode a large number of characters ignored by the built in method including apostrophes.
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="html"></param>
        /// <returns></returns>
        public static string EncodeFull(this HtmlHelper helper, string html)
        {
            var result = helper.Encode(html);
            foreach (var replacement in Replacements)
            {
                result = result.Replace(replacement.Key, replacement.Value);
            }
            return result;
        }
    }
}

And here is a unit test for it, this uses the HtmlHelperFactory class I described here:

using System.Linq;
using System.Web.Routing;
using KableDirect.Web.FrontEnd.Helpers;
using MbUnit.Framework;

namespace KableDirect.UnitTests
{
    [TestFixture]
    public class TestHtmlEncode
    {
        [Test]
        public void test_all_chars_are_encoded()
        {
            var html = HtmlHelperFactory.CreateInstance(new RouteData());
            var specials = "–—‘’‚“”„†‡•…‰€™ŒœŠšŸƒ’ÀàÁáÂâÃãÄäÅåĀāĂ㥹ǞǟǺǻÆæǼǽḂḃĆćÇçČčĈĉĊċḐḑĎďḊḋĐđÐðDZDzdzDŽDždžÈèÉéĚěÊêËëĒēĔĕĘęĖėƷʒǮǯḞḟƒfffiflffifflſtǴǵĢģǦǧĜĝĞğĠġǤǥĤĥĦħÌìÍíÎîĨĩÏïĪīĬĭĮįİıIJijĴĵḰḱĶķǨǩĸĹĺĻļĽľĿŀŁłLJLjljṀṁŃńŅņŇňÑñʼnŊŋNJNjnjÒòÓóÔôÕõÖöŌōŎŏØøŐőǾǿŒœṖṗŔŕŖŗŘřɼŚśŞşŠšŜŝṠṡſßŢţŤťṪṫŦŧÞþÙùÚúÛûŨũÜüŮůŪūŬŭŲųŰűẀẁẂẃŴŵẄẅỲỳÝýŶŷŸÿŹźŽžŻż";
            var encoded = html.EncodeFull(specials);
            var specialChars = specials.ToCharArray();
            var missedChars = encoded.ToCharArray().Intersect(specialChars);
            string output = "";
            foreach(var ch in missedChars)
            {
                output += "{\"" + ch + "\", \"&#" + ((int) ch) + ";\"},\n";
            }
            Assert.IsEmpty(output);
        }
    }
}
 

301 redirects from Asp.Net February 9, 2010

Filed under: Asp.Net,guardian.co.uk,Uncategorized,Web — Rupert Bates @ 2:29 pm

Using Response.Redirect in Asp.Net will issue a 302 (temporary redirect) response. For items that have moved permanently you should issue a 301 (permanent redirect) using code such as:

<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
    Response.StatusCode = (int) HttpStatusCode.MovedPermanently;
    Response.Status = "301 Moved Permanently";
    Response.AddHeader("Location", "http://www.my-redirect.co.uk/newhomepage.aspx");
}
</script> 

Paul Roach the SEO lead at guardian.co.uk explains why this matters:
“301 redirects are preferable from an SEO point of view because they instruct the search engine to pass all of the value of the original page to the destination page, including link equity and page history / age. If you use 302 redirects the search engine considers it a temporary state and does not pass the value from the original page to the destination page, this can also lead to both pages being displayed in the index.”

 

New .Net Client Library for Guardian Open Platform November 26, 2009

Filed under: Asp.Net,C#,guardian.co.uk,Web — Rupert Bates @ 10:30 am

I’ve recently created a .Net client library for the Guardian’s Open Platform API which allows you to query guardian.co.uk, pull back content and ‘Build applications with the Guardian’.

The project is open source and hosted on codeplex.

You can find out more about the Open Platform API here:

http://www.guardian.co.uk/open-platform