views:

379

answers:

2

Hi.

I have a C# ASP.NET MVC project but my controllers are written in F#.

For some reason, the following code doesn't work properly.

namespace MvcApplication8.Controllers

open System.Web.Mvc

[<HandleError>]
type ImageController() =
  inherit Controller()

  member x.Index (i : int) : ActionResult =
    x.Response.Write i
    x.View() :> ActionResult

The parameter of the action is seemingly ignored.

http://localhost:56631/Image/Index/1

=>

The parameters dictionary contains a null entry for parameter 'i' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult Index(Int32)' in 'MvcApplication8.Controllers.ImageController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters     

The controller otherwise works fine. I know that plenty of people have written F# mvc code, so, any ideas where I'm going wrong?

+1  A: 

what's your Route look like? is it routing to id? in which case rename i to id

Keith Nicholas
That was it -- thanks!
Matt H
+4  A: 

The problem is that the name of the parameter of the controller needs to match the name specified in the mapping that specifies how to translate the URL to a controller call.

If you look into the Global.asax.cs file (which you should be able to translate to F# too), then you would see something like this:

routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", 
          id = UrlParameter.Optional } // Parameter defaults
);

The name id specifies the expected name of the parameter, so you need to adjust the F# code to take a parameter named id like this:

member x.Index(id:int) =
  x.ViewData.["Message"] <- sprintf "got %d" id
  x.View() :> ActionResult

You can use Nullable<int> type if you want to make the parameter optional.

For a programmer used to the static type safety provided by F#, it is somewhat surprising that ASP.NET MVC relies on so many dynamic tests that aren't checked at compile-time. I would hope that one day, there will be some nicer web framework for F# :-).

Tomas Petricek
Dang it! I completely forgot about that. I so was convinced that it was an F#-related problem that I forgot to go back to the ASP.NET MVC basics.Thanks alot!
Matt H