A MVC-ish approach to WebMatrix (WebPages)

I like the dynamic approach of WebMatrix a lot. However I do not like the “put everything in one file” way as the built in templates are using. Where for example the simple login form is one single 100 LOC’s file. I’d like the nice Controller – View separation as in MVC. Also I like the nice Restful Url’s. And guess what – it’s a no brainer to get all of this in WebMatrix.

Given the built in default semi-magically routing of WebMatrix I came up with a solution with a controller as a cshtml file in the root of my project, and the views in a folder with the same name:

Now all URL-calls starting with “mysite.com/projects” will actually be handled by projects.cshtml.

That goes for mysite.com/projects as well as mysite.com/projects/edit/3. And its up to projects.cshtml to handle the calls as appropriate. Just as a MVC controller should.

The index page (served by projects.cshtml)

The edit page (also served by projects.cshtml)

The view files are prefixed with _ to stop them from being called directly (a convention used by WebMatrix).

A View

The _edit.cshtml stub looks like this:

<!DOCTYPE html>

<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <h2>Edit record</h2>  
        @Page.Model
        <form method="post"><input type="submit"/></form>   
        <a href="/projects">Back to list</a>
    </body>
</html>

Where I have the dynamic Page to serve me Page Model data. There I can put whatever I need, just like the ViewBag in Asp.Net MVC3.

Edit: Updated to use the @functions approach from Separating html and logic in razor

The Controller

And the Controller, projects.cshtml looks like this:

@RenderPage(view)
@functions{

    private string action;
    private string id;
    private string view;

    protected override void InitializePage()
    {
    // Get first verb from Url and use as action
    var action = UrlData[0].ToLower();  
    
    // Get second verb and use it as id.
    var id = UrlData[1];
    
    // Example:
    // mysite.com/projects/edit/0
    // UrlData[0] returns "edit"
    // UrlData[1] returns "0"
    
    // Now act on the action verb:    
    switch(action) {       
            
        case "edit":
            if (!IsPost)
            {
                // get model data and send it to the view via the Page object
                var GetDataModelFromDb = "MockData for record # " + id;
                Page.Model = GetDataModelFromDb;
                
                // render view
                view = "/projects/_edit.cshtml";
                }
            else
            {
                // <strong>Handle update</strong>
            }
            break;

        case "delete":
            
            if (!IsPost)
            {         
                var GetDataModelFromDb = "MockData for record # " + id;
                Page.Model = GetDataModelFromDb;                
                view = "/projects/_delete.cshtml";        
            }
            else
            {
                //<strong>Handle delete</strong>
            }            
            break;
            
        default:
            
            view = "/projects/_list.cshtml";        
            break;
        }
    }
}

That’s it – now I have a controller that I can edit just as dynamically as my views.

Disclaimer: I could miss something obvious here, a security issue or whatever.

If you have some input regarding security or anything else really, please post a comment, I would be very happy to hear from you. Thanks alot.

Reference:
WebMatrix URLs UrlData and Routing for SEO

Next thing I like to do is to create a @helper for constructing of my Html forms, and also a TryUpdateModel-function to help me with the updates. Also on my to-do-list for this project: add form validation using jQuery validate and unobstrusive javascript.

Advertisements

One thought on “A MVC-ish approach to WebMatrix (WebPages)

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s