harriyott.com

4 August 2010

Error starting site in IIS

I got the following error message when trying to start a site on port 80 in IIS

Internet Information Services (IIS) Manager

The process cannot access the file because it is being used by
another process. (Exception from HRESULT: 0x80070020)

Following the instructions here, I:

  1. Ran netstat -aon | find ":80" from a command prompt
  2. Found the PID for the process using port 80
  3. Used Task Manager to find out what program owned this process. It turned out to be Skype.
  4. Closed Skype. Lo, I can now start the site in IIS

29 July 2010

Strange, kind of sad, big old error.

Strange Visual Studio 2010 error message today, with absolutely nothing on Google.

VsTextViewAdapter initialization failure: Trying to create a text view without an available text buffer, current state:Sited

The project is ASP.NET MVC 2.0, and any views that were open when the project was closed are being reopened, but nothing is being rendered, even in code view. Trying to open a C# file produced this error:

Internal error occurred. Additional information: ''.

Thanks for that. Pressing F5 to run the solution in debug mode just crashes VS without any error.

After trying a few other files and projects, I rebooted, and it was all fine.

Keep calm and turn it off and on again by Adam Bowie

2 June 2010

Dynamic numbered map pins with ASP.NET MVC

A mapping project I've recently been working on needed to have coloured, numbered pins to correspond to the numbered items shown in the list below the map, e.g.
Green 23 marker

I wanted the images to be created dynamically, as the numbers could reach into the hundreds, and I didn't fancy spending several days with Photoshop. I started with empty pin images (red, green, blue and black).
Empty marker

To improve performance, I decided to write the image to disk once I'd generated it, which I could just return in future calls. I also wanted to cache the image path, so I wouldn't have to access the disk to see if the image had been created already.

I added an ImageController class, and an Index action that took the colour as a string and the number as an integer:

public ActionResult Index(string colour, int number)

This would correspond to the url http://domain.com/image/green/23.png. I put the png extension so everything would know it was a png file. So after checking that an existing image for the colour and number didn't exist, one needed to be generated. I've not used the graphics classes in .NET before, so I was super excited about it. The first step was to load the correctly coloured image:

using (var stream = new FileStream(imageRoot + colour + ".png") {
  image = Image.FromStream(stream);
}

Now to draw the number on top of the image:

var g = Graphics.FromImage(image);
g.TextRenderingHint = TextRenderingHint.AntiAlias;
var stringFormat = new StringFormat
  {
    Alignment = StringAlignment.Center,
    LineAlignment = StringAlignment.Center
  };
g.DrawString(
  number.ToString(),
  SystemFonts.DefaultFont,
  Brushes.Black,
  new RectangleF(0f, 0f, image.Width, 33f),
  stringFormat);

This is just setting up the text style, defining a rectangle in the right place, then drawing the string into the rectangle. (I still can't help thinking of Speedos.) Then it was a simple case of saving the image for next time and returning it as a FilePathResult:

image.Save(imagePath, ImageFormat.Png);
return File(imageUrl, "image/png");

25 May 2010

New blog platform

Due to blogger.com discontinuing FTP publishing support for domains (thanks Google), I couldn't update my blog. Not only that, nobody could post a comment either.

Blogger.com has server me well for nearly 7 years (84 in internet years), so there's bound to be a suitable .NET blog platform to suit my basic needs, i.e. no database (as my cheapo host doesn't support SQL Server and I don't want to change host as well.

It turns out that there wasn't a .NET blog platform to suit my needs, so I'm writing one. This is the first post with it, and very happy I am with it too. Each blog post is stored as an XML file in blogml format. I'm using disqus for the comments

13 January 2010

Adding SEO fields to N2 MVC example

I've been using (a copy of) the MVC example from the N2 trunk. By default, there is no SEO tab. To add this, copy SEODefinitionAppender.cs and TitleAndMetaTagApplyer.cs from the N2.Templates.Mvc project (Services folder) to the example project. Then add the line
engine.AddComponent("n2.templates.seo.definitions",
typeof(SEODefinitionAppender));
to the end of Application_Start in global.asax.cs.
The SEO tab and fields should now appear on the edit page.

The next step is to get the SEO fields into the master page. If there's no code-behind class for the master page, then add one, and derive the class like so:
Site : ViewMasterPage<IItemContainer>, IItemContainer<ContentItem>

Add the following to the class:
protected override void OnInit(EventArgs e)
{
_titleApplyer = new TitleAndMetaTagApplyer(this.Page, Model.CurrentItem);
}

public ContentItem CurrentItem
{
get
{
return Model.CurrentItem;
}
}
Derive AbstractPage from IItemContainer, and implement the CurrentItem getter by returning "this". Make sure all view pages' view data is derived from AbstractPage or IItemContainer.

6 January 2010

Setting up N2, the open source, ASP.NET (with optional MVC) CMS

Here's what I did to get started with N2, the best CMS I've used to date. I've not set up one of these for a while, so I thought I'd document the process:

  1. Check out the latest source from the subversion trunk - http://code.google.com/p/n2cms/source/checkout
  2. Ran Prepare_Dependencies-vs2008.bat in the root folder
  3. Ran Build_Everything-vs2008.bat, also in the root
  4. Made a copy of examples/Mvc to use as a new project
  5. Loaded the solution in VS2008
  6. Created the database, and ran the script
  7. Built and ran the project
  8. Navigated to /edit/install to see how I was doing


Not very well. I got a "No component for supporting the service N2.Web.Mvc.IControllerMapper was found" error. Google told me very little, except that someone else had the same problem and posted it on the forum. I posted too, and within half an hour, Steve Mason (who I worked with at Cubeworks, and is a contributor to N2) had replied asking for a stack trace. I provided one, and Steve provided the fix. Back on track.

I then checked /edit/install again, which prompted me to upgrade to version 2 of the database, by simply clicking a button. It then told me to add a root page, which I did. Now I'm up and running.

After copying a page or two, I kept getting a StackOverflowException thrown. Thanks to Joel and Jeff, these are harder to google for, but eventually I worked out that I needed to override TemplateUrl in the Model class (derived from AbstractPage).

3 November 2009

NHibernate.MappingException

Just got this error message and had no relevant results on Google:

System.TypeInitializationException : The type initializer for 'MyApp.Repositories.NHibernateHelper' threw an exception.
----> NHibernate.MappingException : An association from the table MyTable refers to an unmapped class: MyApp.Domain.MyClass

Schoolboy error; I'd forgotten to mark the hbm.xml files as embedded resources.

2 November 2009

Windows Installer 4.5 Installation Error on XP

While attempting to install Windows Installer 4.5 from the WindowsXP-KB942288-v3-x86.exe file, an error occurred prompting me to select a debugger. The error was to do with update.exe.

After a couple of attempts, I realised that it was still at the unzipping stage of the install, so I loaded up WindowsXP-KB942288-v3-x86.exe in 7-zip and extracted the files. I was then able to run the installer from the extraction.

7 October 2009

SEO Adventures

Earlier this year, when I was nearing the end of a contract, I redeveloped my website. As a web developer, I needed my professional site to look like I knew what I'm doing.

As well as looking good, I wanted the CV page to show up high in Google. I applied some of the SEO techniques I'd learnt over the years, and avoided some of the more dubious ones I'd seen some people do.

Firstly, I worked out which keywords I wanted to do well on. I already do rather well for searches for 'Simon Harriyott', but (and I have no idea why) not many people search for me by name. As I'm a C# developer and contractor, and it's my CV page, I chose the keywords C#, ASP.NET, developer, contractor and CV. Since CV is an abbreviation, I include Curriculum Vitae in the list. If I was interested in working in America, then Resume would also be needed.

So now I have some keywords, where did I put them? Starting from the top, I added them to the title tag. I already have my name in the title, so it could be quite long. Google places more importance on the first words in the title, so I shoved my name to the end, and slotted in C# at the beginning.

Next were the meta tags. The description and keywords were given a similar treatment.

In the body, the heading tags are important, and as you'd expect, the H1 is the most important, so keywords were added there. The main body copy needed the the keywords scattered about too, but in a subtle, not too obvious kind of way. This is the tricky bit, as people will (hopefully) read the words, so they need to make sense as well as be attractive to the big G.

I put some of the keywords in strong tags too, which are given more value than if they were left as they were.

In addition to this, I spent five years writing a blog, and getting some incoming links various pages on my domain. I could have put more effort into it, but I'm a developer first and blogger second, so the homepage has a PageRank of 3. This helps too, but a 4 or 5 would help a lot more.

I also have owned the domain for many years. Google prefers older sites, or domains that are registered for more than a year. New sites with a one-year registration may be used for spammy purposes.

A while after I'd deployed the CV page, I checked the results on google.co.uk, and found I was the first result (oh yes) for 'C# CV' and 'ASP.NET CV'. This is cool for a couple of reasons: firstly it worked, and secondly, I can tell people to go to Google, type 'C# CV' and press the I'm feeling lucky button. Well, in theory I could, but it sounds a bit cheesy.

I should check where the page appears for other combinations of the keywords, but I'm too scared to change anything while I'm number 1.

Please note that while I'm happy to attempt to improve clients' sites for SEO, it's an art, not a science, and some keywords are so saturated that it'd be much cheaper to pay for Adwords.

17 September 2009

Availibility

My current contract is finishing on 30th September, so I'm available for C# contract work from 1st October. More details about what I'm good at are on my CV.