Tuesday, April 28, 2009

ASP.NET MVC template with Spark

What it Spark?

Spark is a view engine for Asp.Net MVC and Castle Project MonoRail frameworks. The idea is to allow the html to dominate the flow and the code to fit seamlessly.

Here's an ASP.NET MVC template that you can put into your "Visual Studio 2008\Templates\ProjectTemplates\Visual Web Developer" folder and start using Spark as view engine.

MvcWebApplicationSparkProjectTemplatev1.cs.zip

All the views as well as the user control used to display log on information has been translated!

Enjoy!

Monday, April 27, 2009

Installing Oracle XE on Ubuntu

I've faced a dilemma today. I need an instance of Oracle XE datababase. The question however is "should I install the windows version on my box?". Since this is not the first time I've been doing it the answer was quite obvious: NEVER EVER DO THAT!

VMware Player to the rescue!

You might ask why wouldn't I install Oracle XE on my Windows box. The answer is plain and simple: I use my notebook for more than just data serving and allowing the Oracle to spread throughout the available resources would be a perfect waste of hardware.
So I did as follows: I've installed Ubuntu 9.04 server (very nice linux distribution indeed!!!), installed the necessary stuff I can't live without (openssh-server, tomcat6, mc, htop), used this tutorial to install Oracle XE, used this tutorial to configure web access to Oracle database manager for external hosts and that's it! It took an hour to get it to work from scratch and the time is really well spent!

One must not forget to allocate quite a lot of swap memory during installation. Automatic disk partitioning is out of the question here. I've created my swap partition to be 1.5 GB in size and that was enough to install Oracle XE.

The final product is 3.5 GB in size, has VMware Tools installed (taken from VMware Server) and performs extraordinary well! Long live virtualization!!!

See ya!

Saturday, April 25, 2009

VirtualPathProvider example

Hi there,

did you ever wonder if you can retrieve ASP.NET MVC views from another storage than a file on disk? For example from the database? This is where the VirtualPathProvider comes into play!

VirtualPathProviderExample.zip

This simplistic example shows how to implement retrieval of data from a predefined string (ugly long string but that's not the point here). You can use some other backing store (database, ftp or even web service!) to get the content.

Enjoy!

Friday, April 24, 2009

Thursday, April 23, 2009

New NUnit template for ASP.NET MVC

Hi,

I've been doing a little bit research in the area of mocking frameworks for different platforms and picked in total 3 clear winners:

- Java: Mockito
- .Net: NUnit (it's there anyway...) and Moq

Here you'll find the new NUnit test template for ASP.NET MVC that also contains a reference to Moq for convenience. Other than that it's the same template as the previous one. However expect that to change in the near future as I'll be porting the manual mocks in AccountControllerTest to Moq.

ASP.NET-MVC-NUnitAndMoqTemplate.zip


Have fun!

Splitting an ASP.NET MVC application into modules

I've been playing a little bit with the concept of splitting an ASP.NET MVC application into some sort of modules so that the final product can be developed separately and (possibly) reused.

Splitting the code into class libraries is easy - you just reference the class library from your main project and that's it. The tricky part is to get the pages into the main project in some usable way.

To solve this riddle I've first created an example ASP.NET MVC application and a class library in the same solution. The class library has been given the following dependencies:

- System.Web.Abstractions
- System.Web.Mvc

and by doing so I was able to effectively create controllers in my class library.

As for the pages I've created a folder called Views in the same way it's done in a regular ASP.NET MVC application but this time in the class library itself. The content of this folder is pretty much the same as with the regular application (\Views\controllername\viewname.aspx).
To get the pages copied to the main project I've used the AfterBuild target as follows:

<Target Name="AfterBuild">
<Exec Command="xcopy /Y /E /R /I Views ..\MVCPluginExample\Plugins\Views" />
</Target>

Hint: to get IntelliSense to work I needed to copy the Web.config from main project to the root of the class library. It works like a charm!

Furthermore I didn't want the "plugin" (so to speak) to be directly referenced from the main project (so that I can really plug'n'run additional parts of the application as needed). To achieve that I've created additional Exec tasks in the AfterBuild target:

<Target Name="AfterBuild">
<Exec Command="xcopy /Y /I /R $(OutputPath)$(AssemblyName).dll ..\MVCPluginExample\bin" />
<Exec Command="xcopy /Y /I /R $(OutputPath)$(AssemblyName).pdb ..\MVCPluginExample\bin" />
<Exec Command="xcopy /Y /E /R /I Views ..\MVCPluginExample\Plugins\Views" />
</Target>

With that at hand I'm able to debug the code in the class library because of the presence of .pdb file and all my views are nicely packaged in separate plugin projects.

But that's not all. To be able to use the views from controllers contained in the library (and to have them in a separate location so that I can easily clean up the main project) I was forced to use constructs as follows:

public ActionResult Index() {
return View("~/Plugins/Views/Home/Index.aspx");
}

Naturally it's a mess and one should never need to specify the full path to the view. It just doesn't make any sense.

It turns out that the list of locations where the MVC engine looks for views is stored in three fields: MasterLocationFormats, ViewLocationFormats and PartialViewLocationFormats (as per WebFormViewEngine.cs lines 23, 28 and 35). Since all we want to do is to instruct the engine to look for views in one more location (~/Plugins/Views/...) all we have to do is to inherit from WebFormViewEngine class and create a constructor that will provide this information. Here's the piece of code that does just that:

public class PluginAwareWebFormViewEngine : WebFormViewEngine {
public PluginAwareWebFormViewEngine() : base() {
ViewLocationFormats = new[] {
"~/Plugins/Views/{1}/{0}.aspx",
"~/Plugins/Views/{1}/{0}.ascx",
"~/Views/{1}/{0}.aspx",
"~/Views/{1}/{0}.ascx",
"~/Views/Shared/{0}.aspx",
"~/Views/Shared/{0}.ascx"
};

PartialViewLocationFormats = ViewLocationFormats;
}
}

Now we can finally get back to providing view names instead of file names in the controller action methods:

public ActionResult Index() {
return View("Index");
}

or even

public ActionResult Index() {
return View();
}

To register this new ViewEngine add the following line to Application_Start event handler in Global.asax.cs

ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new PluginAwareWebFormViewEngine());

What this does is it makes sure that there's only one view engine that is in fact modified by us.

Here you can download the complete solution.

mvc-plugin-example.zip


Have fun!

Saturday, April 18, 2009

Visual Studio Web Developer Server and PHP

Today I've been looking for a solution that would allow me to serve PHP pages from my web application. Unfortunately it turns out there's no default handler for CGI applications. However Ziya Suzen has already created an IHttpHandler that does the job.

Remember: all the credits for this solution go to Ziya Suzen


PHP-Example.zip

Here you can find a complete solution that does just that: when executed from within Visual Web Developer it shows a list of files in a browser and when you select index.php you'll get a nice text "Hello, world!" that's being generated by PHP.

A few notes about the modifications I've made:

1. The php-cgi.exe executable has a fixed path build in. It's X:\programs\php\php-cgi.exe.
2. For some (yet) unknown reason the PHP script processor complains when the REQUEST_METHOD variable is set so I've commented it out.

Have fun!

PHP on MS platform???

Hi,

it looks like that MS is hitting at the PHP web page developers out there by providing a unified installer for PHP and PHP-based applications in their web-platform installer. Check it out here

Enjoy!

Friday, April 17, 2009

DynamicData cleanup

Last time I've described a way of merging the DynamicData capability with an ASP.NET MVC application. This time I'll show you how to make the DynamicData part be stored in the right place.

First of all it's kind of awkward to have the Site.css, Site.master and the rest in the root folder. Let's face it: this sucks! It'd be nice if we could have those DynamicData-related stuff inside the DynamicData folder where they could live happily ever after.

It's not impossible but there are two small glitches that you need to be aware of. But first things first.

Step 1. Grab the Site.css, Site.master in solution explorer and drag them to the DynamicData folder.

Step 2. Open the DynamicData\Site.master file and change the

<img alt="Back to home page" runat="server" src="DynamicData/Content/Images/back.gif" />

with

<img alt="Back to home page" runat="server" src="~/DynamicData/Content/Images/back.gif" />

Node the Tilda addition in the image src attribute!

Step 3: Change the master page for pages. In the folder DynamicData\PageTemplates you'll find templates for all the generated pages. Open them one by one (there are 5 of them: Details.aspx, Edit.aspx, Insert.aspx, List.aspx and ListDetails.aspx) and change the MasterPageFile attribute from

MasterPageFile="~/Site.master"

to

MasterPageFile="~/DynamicData/Site.master"

That's it! There's nothing more to it. From now on your application structure is cleaner and there's noting polluting the clear ways of the ASP.NET MVC project!


Have fun!

Adding DynamicData to an ASP.NET MVC application

In my previous post I've pointed you to a place that contains a ready-to-use solution on how to use DynamicData with ASP.NET MVC. In this post I'll describe the manual way of doing that so that you can see that there's no mystery hiding behind the scenes.

I'm going to assume that you have an up-and-running project created using ASP.NET MVC Application template.

Step 1: Create a separate DynamicData project. Call it whatever you want - we're going to need a few files from that project.

Step 2: Copy the following files from the DynamicData project right into the MVC application and include them in the MVC project:

  • /Site.css

  • /Site.master

  • /Site.master.cs

  • /Site.master.designer.cs

  • /DynamicData (the whole folder!)


Step 3: We need to register the DynamicData engine in our application. To do that copy the following lines from the Web.config file in DynamicData project into the Web.config file in ASP.NET MVC project:

  • from \\configuration\system.web\compilation\assemblies
    <add assembly="System.Web.DynamicData, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

  • from \\configuration\system.web\pages\controls
    <add tagPrefix="asp" namespace="System.Web.DynamicData" assembly="System.Web.DynamicData, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

Step 4: Add a reference to System.Web.DynamicData to the MVC project.

Step 5: Register routes in Global.asax.cs. Depending on the context you'll have to adjust the context registration. Here I'm using the Northwind data context:

MetaModel model = new MetaModel();
model.RegisterContext(
typeof(MvcApplication1.Models.NorthwindDataContext),
new ContextConfiguration() {
ScaffoldAllTables = true
});
routes.Add(
new DynamicDataRoute("DD/{table}/{action}.aspx") {
Constraints = new RouteValueDictionary(
new { action = "List|Details|Edit|Insert" }),
Model = model
});

Make sure you add the proper using statement to System.Web.DynamicData and your models!

Step 6: Add a listing of all the tables to your Views/Home/Index.aspx:

<% foreach (MetaTable table in MetaModel.Default.Tables) { %>
<li>
<a href="<% =table.GetActionPath("List") %>">
<% =table.DisplayName %>
</a>
</li>
<% } %>


Done!

Run your application. On the initial page you should see a clickable list of all the tables from your database.

Enjoy!

DynamicData with ASP.NET MVC

Recently while browsing the web for interesting resources I've stumbled upon a blog entry talking about DynamicData. Since I've had no idea what that was I've dug a little bit into it and found out that it poses a fantastic opportunity to complement an otherwise complete site with a nice browser/editor for the whole database.

Since it was all nice and dandy I've dug a little bit more trying to integrate this technology with the ASP.NET MVC framework. And as it turns out there's a great example here that provides an end-to-end solution.

Since I've had some trouble running this example out-of-the-box I though I'd share what I've done to make it work:

1. Open the ~/Views/Shared/Site.Master
2. Add the following line right after the page declaration:

<%@ Import Namespace="System.Web.Mvc.Html" %>


That's it! Just hit F5 and observe the beauty of the DynamicData integrated with ASP.NET MVC :D

Have fun!

Linking resources in ASP.NET MVC

Working on web sites that have dynamic URLs (like the ones in ASP.NET MVC or JSF) poses one difficulty: you never know where to look for resources such as images or CSS files. This is due to the fact that the same view can have more than one address. Let me give you an example:

/Demo/ -> this should render the default controller (HomeController) with the default view (Index.aspx).
/Demo/Home -> this should render the specified controller (again HomeController) with the default view (Index.aspx)
/Demo/Home/Index -> this should render the specified controller (again HomeController) with the specified view (Index.aspx)

So how do you go about specifying an URL for resources in this case? Well there are different ways to do that.

1. You could create and use an Html helper method to do that.
2. You could hard-code the absolute paths (like /Demo/Content/Index.css for example)
3. You could make use of the runat attribute and use relative paths.

I personally dislike the first and second options. They tend to introduce mess to my otherwise clear code. The third option is in my opinion the best one.
Here's an example of how you'd create a link to a CSS:


<link type="text/css" href="~/Content/Site.css" runat="server" />


Happy coding!

Wednesday, April 15, 2009

NUnit template for ASP.NET MVC

Hi there,

I've been struggling a bit with the automatic addition of NUnit unit tests to ASP.NET MVC project in Visual Web Developer. I wanted to have it the same way it works with the VisualStudio unit test framework that is being shown over and over again on the net.

So here's the complete solution: just unzip it, run install.bat and enjoy!

ASP.NET-MVC-NUnitTemplate.zip

Additionally to the standard files you'd expect to be in place there's a NUnit project file called UnitTests.nunit. It's already configured and ready to go. To open it with the NUnit test runner do a right click on it, select "Open with...", add a new program by using the "Add" button, select the nunit.exe file, click ok, highlight NUnit in the list, click "Set as Default" and click OK. From now on everytime you double-click on it you'll run the NUnit GUI test runner which is pretty much what you'd expect.

Padcom.