ASP.NET MVC MonoDevelop Addin Preview

The past month or two, in addition to bugfixing for our recent MonoDevelop 2.0 release, I've been quietly hacking on a MonoDevelop Addin to support writing ASP.NET MVC applications. Those of you following me on Twitter may have picked up a few hints...

Now that Microsoft has released ASP.NET MVC under the MS-Pl licence, I'm making a preview release of the ASP.NET MVC addin for people who'd like to start playing with this exciting new tech on Mono. It's relatively immature, so don't expect everything to work perfectly, but it handles creating and running a VS-compatible ASP.NET MVC project just fine.

You'll need MonoDevelop 2.0 and Mono 2.4 or later. Make sure you have the package that contains System.Web.Abstractions/Extensions/Routing; on SUSE this is currently mono-extras. The addin includes a copy of the System.Web.Mvc.dll, so you don;t need to do anything special for that.

The addin is in the default MonoDevelop addin repositories (though I may be releasing updated versions from my own repo at http://mjhutchinson.com/mdrepo), so open MonoDevelop, click on the Tools->Add-in Manager menu, and click the Install add-ins... button. Select the ASP.NET MVC addin, and complete the installation.

Installing the ASP.NET MVC Addin

Restart MonoDevelop, as there seems to be a minor issue with reference assemblies updating dynamically.

Now you can create new ASP.NET MVC projects.

Creating a new ASP.NET MVC project

When you create a new project, you'll see a project with all the basics set up, but minimal content, so that you don't have to worry about stripping out things you don't need. If even the "Hello World" view is too much, there's also an "Empty ASP.NET MVC Application" template.

There's an "Add View" command on the context menu for the Views folder, and an "Add Controller" command on the context menu for the Controllers folder.

The Add View Menu

Similarly to the Visual Studio ASP.NET MVC tooling, you can add custom T4 templates for the "Add View" command. As part of developing this feature, I implemented an open-source T4 engine from scratch, which Miguel already blogged about. I also added some syntax highlighting, code folding, and a document outline, and T4 compilation errors are reported in the error pad so you can jump to the error location.

The Add View dialog showing a custom TT template

I'm not happy with the restrictive nature of the ASP.NET MVC T4 host, but initially I went for compatibility with MS' version. In future I'd like a way for these templates to be able to output multiple files and expose additional properties to the GUI, and for the GUI to hide settings that the templates don't support. Note also that the "Strongly Typed" model class option is disabled, as the ASP.NET MVC T4 host exposes a type object for this, whereas MD doesn't load actual types. I'm trying to figure out a way around this.

And the proof that it works with Mono and MD? Hit F5 to build and run.

Running the default Hello World view

There are many more exciting features that I'd like to add, though I have many other things on my plate right now, such as improving MD's Mac support, so contributions are very much welcome.

Comments

Hi and thanks a lot for your effort, pretty good job.

However I was seeing some issues with default route parameters, it seems like they're ignored if they're not provided in the URL:

For example:

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

Will never work because it states it cannot find the controller:
value name controller does not match any of the values.

If i change my route to this:
routes.MapRoute(
"Default",
"{controller}/Index",
new { controller = "Home", action = "Index", id = "" }
);

It will start stating it cannot find the action.

If i change to route to
routes.MapRoute(
"Default",
"{controller}/{action}",
new { controller = "Home", action = "Index", id = "" }
);

It works fine if i provide /Home/Index but won't work if i provide one or the other. Where do i file bugs like this? I'm kind of
new to the mono community.

Cheers,
Alfred

I must admit, I've had barely any time to use ASP.NET MVC myself, and I tried not to copy the MS templates directly, so there are likely some bugs in the templates. Any suggestions you can make to improve them would be most welcome!

There are instructions for reporting MonoDevelop bugs at http://monodevelop.com/Developers#Reporting_Bugs

Hello, thanks very much for making this available; I'm very excited to begin diving into the new MVC framework! Maybe I'm missing something obvious, but is debugging currently supposed to work? I try to set breakpoints in my View and Controller and then run F5 but they never get hit.

The Mono debugger doesn't yet support debugging ASP.NET, so MonoDevelop is unable to offer this feature. However, this feature isn't far off — it should be in MonoDevelop 2.2 (as long as you also have Mono 2.6 or later).

Looks like our replies crossed in the mail, thanks for the heads up... direct ASP.NET debugging will be nice but in the meantime NUnit testing of the controller will suffice. I'm not thrilled about the startup time for running the NUnit tests, but I guess that just means I'll have to get my code right the first time :)

You can run NUnit tests individually using the test pad. I've always found this to be pretty fast. If startup time is particularly noticeable, it might be worth filing a bug.

OK, after reading your comments on your newer post[1], I realized that debugging is not yet supported for ASP.NET in general and not just for the MVC projects. But no worries... one of the benefits of MVC is that the controllers are testable, right?

So I created an NUnit project in the same solution, switched it to framework version Mono/.NET 3.5, then added a reference to my MVC project and to System.Web.Mvc. At first it couldn't find that DLL, but then when I explicitly pointed it to System.Web.Mvc.dll in my project's bin folder, it worked! I can use the NUnit project to debug into my controller class!

I'm very excited about the possibilities that this opens up. Hopefully the day is getting very close when I can finally kiss Eclipse goodbye for good :)

Thanks again for your work on this, I eagerly await further developments in this area!

[1] http://mjhutchinson.com/journal/2009/04/04/monodevelop_aspnet_mvc_mac

That's a neat trick for debugging an ASP.NET project! I wonder why the MVC reference has to be added explicitly...

Hi,

I really like your work, it pushes me a big step forward, thanks for that :)

Compiling and running the sample MVC project was no problem, up running in less than three minutes.

But when I try to build some larger projects, I'm receiving an NullReferenceException:
System.NullReferenceException: Object reference not set to an instance of an object
at MonoDevelop.AspNet.Mvc.AspMvcProject.PopulateSupportFileList (MonoDevelop.Projects.FileCopySet list, System.String solutionConfiguration) [0x00000]
at MonoDevelop.Projects.Project.GetSupportFileList (System.String solutionConfiguration) [0x00000]
at MonoDevelop.Projects.Project.DeleteSupportFiles (IProgressMonitor monitor, System.String solutionConfiguration) [0x00000]
at MonoDevelop.Projects.Project.OnClean (IProgressMonitor monitor, System.String solutionConfiguration) [0x00000]
at MonoDevelop.Projects.DefaultProjectServiceExtension.Clean (IProgressMonitor monitor, IBuildTarget item, System.String configuration) [0x00000]

..... and so on

I'm not sure if this error is only related to the add-in or it is raised due some misbehavior in my project.

Maybe you have a hint for me?

Thanks in advance,

squig

Thanks :)

Can you run MonoDevelop with --debug, to get line numbers in the stack trace?

It looks like I forgot to include the debug symbols in the downloadable addin. I'll see if I can reproduce this myself when I have time.

I am having the same issue. Did you ever figure out the cause of this?

I'm not sure yet, but I suspect you might be able to work around it by removing and re-adding the MVC reference.

I think I fixed it. There's a new build in my MD repository, and when i get confirmation that it fixes the issue, we'll push to the main update repository.

Hi there,

first of all thanks for the tip - it's really great!

About that strongly-typed views: I've created such a page manually and mono 2.4 (both under linux and windows) gives me an error. I suppose that they don't support generic type definition in ASPX header just yet.

ystem.InvalidOperationException: The view 'Index' or its master could not be found. The following locations were searched:
~/Views/Person/Index.aspx
~/Views/Person/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
at System.Web.Mvc.ViewResult.FindView (System.Web.Mvc.ControllerContext context) [0x00000]
at System.Web.Mvc.ViewResultBase.ExecuteResult (System.Web.Mvc.ControllerContext context) [0x00000]
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult (System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ActionResult actionResult) [0x00000]
at System.Web.Mvc.ControllerActionInvoker+<>c__DisplayClass11.b__e () [0x00000]
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter (IResultFilter filter, System.Web.Mvc.ResultExecutingContext preContext, System.Func`1 continuation) [0x00000]

Don't mistake that with the view not being there. After I've removed the generic thing from Page directive everything works just fine.

Best regards,
Padcom

I'm not sure why it doesn't work with Mono... the MVC pages use special ControlBuilders to modify the page compilation process so that you don't have to use CLR syntax.

It doesn't work in the MD Code Completion, since the ASP.NET completion in MD doesn't use ControlBuilders; they'd require instantiating actual types, and I suspect they'd be too slow and fragile. I'll have to add a special case for ASP.NET MVC.

Update: The Mono bug was fixed today.

Also, I was wrong; the magic's in a PageParserFilter, not a ControlBuilder.

Hi!

Im programing a short example following this example:
http://stephenwalther.com/blog/archive/2009/04/13/asp.net-mvc-tip-50-ndash-create-view-models.aspx

The server return always the same error:
The view 'Index' or its master could not be found. The following locations were searched: ~/Views/Home/Index.aspx ~/Views/Home/Index.ascx ~/Views/Shared/Index.aspx ~/Views/Shared/Index.ascx

Description: HTTP 500. Error processing request.

Stack Trace:

System.InvalidOperationException: The view 'Index' or its master could not be found. The following locations were searched:
~/Views/Home/Index.aspx
~/Views/Home/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
at System.Web.Mvc.ViewResult.FindView (System.Web.Mvc.ControllerContext context) [0x00000]
at System.Web.Mvc.ViewResultBase.ExecuteResult (System.Web.Mvc.ControllerContext context) [0x00000]
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResult (System.Web.Mvc.ControllerContext controllerContext, System.Web.Mvc.ActionResult actionResult) [0x00000]
at System.Web.Mvc.ControllerActionInvoker+c__AnonStorey14.<>m__22 () [0x00000]
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter (IResultFilter filter, System.Web.Mvc.ResultExecutingContext preContext, System.Func`1 continuation) [0x00000]

Im reading that you are working on fixing this bug in this URL:
https://bugzilla.novell.com/show_bug.cgi?id=494245

I am writing a tutorial of using ASP.NET MVC in mono, but i cant pass data from controller to view, can you help me???? ;)

Sorry for my bad english...

Regarding bug 494245, it's fixed in SVN, but until we make a release, you can work around it by using CLR syntax for generics in the Inherits attribute. So, instead of
Inherits="System.Web.Mvc.ViewPage<IEnumerable<MvcApplication1.Models.Product>>"
you would use
Inherits="System.Web.Mvc.ViewPage`1[[IEnumerable`1[[MvcApplication1.Models.Product]]]]"

The MVC project that MD creates has an example of passing data from the controller to the view, with ViewData["Message"].

Hi , my problem persists. The example that the MD creates is very simple, I can pass data with ViewData["data"], but i wanna write a little more complex tutorial that a simple hello world, I want to write a complete CRUD tutorial with the MySQL Database.
The example only works if i pass a string, my problem comes when y try to pass some kind of List.
I tryied with the code of this web page,
http://stephenwalther.com/blog/archive/2009/04/13/asp.net-mvc-tip-50-ndash-create-view-models.aspx

but It fails when i pass a generic List from controller to the view. If i use a response.write in the controller it works fine, but this is not the good way.

Have you got some example working with generic List passing from controller to Views???

Sorry again,

Thanks..

I think the problem that you are seeing is that, when the view cannot be compiled, the controller cannot find it. I had to navigate directly to Views/Home/Index.aspx to see the View's errors.

I as able to create a view with a strongly-typed model property (List) using the CLR syntax for generics:
Inherits="System.Web.Mvc.ViewPage`1[[System.Collections.Generic.List`1[[System.String,mscorlib]], mscorlib]]"

Thanks, the example you posted is exactly what i needed.

Now i can continue writing my tutorial.

Its a little more complex syntax but it works fine.

Have the mono project some kind of documentation repository or something like that???? A wiki or something like that??? Or its documentation is all based on the microsoft documentation ???

You are doing a great work with mono, Congratulations to all the mono team!!!

Mono trunk and the 2.4 branch have the bug fixed, so you can use normal generic syntax. Hopefully 2.4.1 will be released soon.

The main Mono site is a wiki, but user accounts are created on request by the admins, because we used to have many spammers when it was open. If you mail the mono list with changes for the wiki, someone will apply them, and maybe create you an account :)

The MonoDevelop site is also a wiki, and since we're using DekiWiki on that, we have more control. However, it's not really the place for generic Mono docs. But it would be the place for a tutorial on creating an ASP.MVC app using MD :)

We also have the online Mono API docs. You can edit the API docs in the MonoDoc GUI app and upload your contributions for moderation.

Of course, MSDN generally has excellent docs, and many of them apply to Mono.

Recientemente (solo un par de semanas) he estado trabajando con ASP.NET MVC 1.0 y una vez que lo he comprendido; lo primero que he hecho es buscar la manera de usarlo con Mono. Y me encuentro con la buena noticia que ya existe el add-in para MonoDevelop. Así pues, comenzaré a probarlo.

Saludos!!

I installed mono 2.6.1 and monodevelop 2.2 for the first time today. I tried to create a new MVC project and I can't compile the auto generated content.

In References it shows System.Web.Mvc in red and states:
Assembly not available for mono / .NET 3.5 (in Mono 2.6.1 (C:\program files...))

And the error I get when I try to compile (obviously):
Warning: Assembly 'System.Web.Mvc' not found. Make sure that the assembly exists in disk. If the reference is required to build the project you may get compilation errors. (monoapi)

The .dll and .pc files exist:

C:\Program Files\Mono-2.6.1\lib\pkgconfig\System.Web.Mvc.dll.pc
C:\Program Files\Mono-2.6.1\lib\mono\gac\System.Web.Mvc\1.0.0.0__31bf3856ad364e35\System.Web.Mvc.dll
C:\Program Files\Mono-2.6.1\lib\mono\2.0\System.Web.Mvc.dll

what am I doing wrong?

I suspect this is specific to discovering assemblies via pkgconfig on Windows, but I can't be sure because I don't work on MD on Windows myself. Could you file a bug?

For the time being you should be able to build it using the .NET runtime, if you install ASP.NET MVC for .NET. When targetting .NET, MD uses the Registry AssemblyFolders like MSBuild and VS do.