Tag Archives: asp.net

Asp.Net MVC 4 on Mono and Windows

Having at last got an Asp.Net Mvc 4 project template working on the Mac/Xamarin/Mono, I came to grief again when deploying it to a Windows hosted server. The problem is that whereas mono works without Microsoft.Web.Infrastructure.dll (and indeed is likely to give errors if you have it), for hosting on Windows you must re-include it.
So my deploy process now includes putting Microsoft.Web.Infrastructure.dll back in the web application bin/ directory; and now I can develop on the Mac and deploy to a Windows Server.

MVC Html.ActionLink() fails weirdly with routeValues parameter in Asp.Net

It seems simple. In an MVC view page you have an @Html.ActionLink with parameters for action, controller & route values:

@Html.ActionLink("Some text","Action","Controller", new {id=1})

but instead of rendering the text with a link to the action, it renders a link with some weird URL that isn’t what you want at all.

If you use intellisense to look at the overloads for ActionLink, you’ll see that the overload you’ve got is interpreting new {id=1} as html attributes not as route values. You need the overload with one more parameter, which can be null:

@Html.ActionLink("Some text","Action","Controller", new {id=1}, null)

And then it works.

Using Castle Windsor DI for controllers in an Asp.Net WebApi Project

There are contrary signals on the web regarding Window DI and the new-ish MVC-ish WebApi IDependencyResolver. Fortunately, by late 2012 Mark Seemann summarised the state-of-the-art: don’t use it.

The reason: it doesn’t allow your DI container to properly manage lifetimes. Instead, do this:

public class WindsorCompositionRoot : IHttpControllerActivator
{
    private readonly IWindsorContainer container;
 
    public WindsorCompositionRoot(IWindsorContainer container)
    {
        this.container = container;
    }
 
    public IHttpController Create(
        HttpRequestMessage request,
        HttpControllerDescriptor controllerDescriptor,
        Type controllerType)
    {
        var controller =
            (IHttpController)this.container.Resolve(controllerType);
 
        request.RegisterForDispose(
            new Release(
                () => this.container.Release(controller)));
 
        return controller;
    }
 
    private class Release : IDisposable
    {
        private readonly Action release;
 
        public Release(Action release)
        {
            this.release = release;
        }
 
        public void Dispose()
        {
            this.release();
        }
    }
}

and wire it up with this line during Application_Start in Global.asax.cs

GlobalConfiguration.Configuration.Services.Replace(
    typeof(IHttpControllerActivator), new WindsorCompositionRoot());

Using Windsor for plain old MVC html pages inside WebApi projects

if you are using MVC controllers with views for html pages as well as IHttpControllers in your WebApi project, then you need to know that the WebApi controllers & activation is a quite separate subsystem from the MVC controllers. You still need the usual WindsorControllerFactory to hook Windsor into the MVC pages as well as the above for the WebApi controllers.

Code for a WindsorControllerFactory can be found in a couple of places, but this is from the Castle Windsor tutorial for Asp.Net 3 and is still valid for Asp.Net 4:

using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Castle.MicroKernel;
 
public class WindsorControllerFactory : DefaultControllerFactory
{
    private readonly IKernel kernel;
 
    public WindsorControllerFactory(IKernel kernel)
    {
        this.kernel = kernel;
    }
 
    public override void ReleaseController(IController controller)
    {
        kernel.ReleaseComponent(controller);
    }
 
    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
        {
            throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
        }
        return (IController)kernel.Resolve(controllerType);
    }
}

and again, you must hook it into the application object in Global.asax.cs

private static IWindsorContainer container;

//These lines should be called during Application_Start
container = new WindsorContainer().Install(FromAssembly.This());
var controllerFactory = new WindsorControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);

// And this in Application_End:
container.Dispose();

Asp.Net MVC Project Guids

The famously unhelpful Visual Studio error message ‘The project type is not supported by this installation‘ usually means that there is something you don’t have installed. But it doesn’t tell you what.

You can work out what you’re missing if you know the Guids to look for in the project file. Look for a line near the top of the file something like this:

<ProjectTypeGuids>{E53F8FEA-EAE0-44A6-8774-FFD645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>

After which you can decode the Guid using either the table here:

Guid Tools Needed to Open Project Build references
{E53F8FEA-EAE0-44A6-8774-FFD645390401} Asp.Net MVC 3 System.Web.Mvc 3.0.0.0
{E3E379DF-F4C6-4180-9B81-6769533ABE47} Asp.Net MVC 4 System.Web.Mvc 4.0.0.0
{349c5851-65df-11da-9384-00065b846f21} Web Designer

Or the more extensive list at http://www.mztools.com/articles/2008/mz2008017.aspx. If you’re stuck try http://google.com/search?q=visual+studio+project+type+guid+list

Can’t open Asp.Net MVC2 project in Visual Studio 2010 – Microsoft.WebApplication.targets was not found

You try to open an MVC2 project that worked on a previous machine but won’t open on your new machine? The error message you get when you try to open the project is:

error MSB4019: The imported project “C:\Program Files\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets” was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.

Possibly your new machine has never had Visual Studio 2008 on it, whereas your old machine did. In which case the solutions is:

  1. Find a machine on which VS2008 has been installed
  2. Copy the contents of C:\Program Files\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications to your new machine

References

http://www.matthidinger.com/archive/2008/11/09/fixing-web-application-projects-with-automated-tfs-builds.aspx