# Monday, December 08, 2008

Avoid using HttpContext in controller actions to make testing much easier. Therefore all inputs to an action needs to be passed as parameters. In my new REST framework that builds on ASP.NET MVC I have created some useful model binders to make this easy.

[ResourceUriTemplate("")]
public class RootUri : ResourceUri
{
    public ResourceResponse Get([HttpCookie] string visited, [AppSetting] int visitTimeout)
    {
    ...
    }
}

The HttpCookieAttribute looks for a cookie called "visited". The AppSettingAttribute looks in web.config for an appSetting with the key "visitTimeout". The method is now easy to test and has very readable definition. :)

 

Both attributes will cast the raw string found into the required type by using a TypeConverter.

The AppSettingAttribute constructor can also take a key name if you want something different from the parameter name.

The code is in SubVersion, but I'll repeat some here to show just how easy it was:

namespace Snooze
{
    public class AppSettingAttribute : CustomModelBinderAttribute
    {
        public AppSettingAttribute()
        {
        }

        public AppSettingAttribute(string key)
        {
            _key = key;
        }

        string _key;

        public override IModelBinder GetBinder()
        {
            return new AppSettingModelBinder(_key);
        }
    }

    public class AppSettingModelBinder : IModelBinder
    {
        public AppSettingModelBinder(string key)
        {
            _key = key;
        }

        string _key;

        public ModelBinderResult BindModel(ModelBindingContext bindingContext)
        {
            string setting = WebConfigurationManager.AppSettings[_key ?? bindingContext.ModelName];
            object value;
            if (bindingContext.ModelType == typeof(string))
            {
                value = setting;
            }
            else
            {
                value = TypeDescriptor.GetConverter(bindingContext.ModelType).ConvertFromString(setting);
            }
            return new ModelBinderResult(value);
        }
    }
}

.net | mvc | REST | web
Monday, December 08, 2008 8:55:53 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Sunday, December 07, 2008

Filters in ASP.NET MVC provide a great way to attach functionality around controllers. By building on top of the MVC framework, my ResourceUri class (which inherits from Controller) gets all the filter goodness as well.

My library also has a SubResourceUri class. Any filters applied to the parent ResourceUri are also executed for the SubResourceUri.

[ResourceUriTemplate("customers/{CustomerId}")]
[MyLoggingFilter]
public class CustomerUri : ResourceUri { ... }

[ResourceUriTemplate("orders/{OrderId}")]
public class OrderUri : SubResourceUri<CustomerUri> { ...}

For example, when we GET an order the filter still catches the request and outputs logging information.

Another use is authorization. You can place an authorization filter on top level URI and it will protect all sub-URIs beneath it.

 

Keep track of the latest developments on the code here: http://svn2.assembla.com/svn/snooze/branches/aspnet

.net | mvc | REST | web
Sunday, December 07, 2008 9:34:25 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Sunday, November 30, 2008

Continued work on my resource-oriented library for ASP.NET MVC has expanded to include an XDocument based view engine for ASP.NET MVC.

This means we can now use VB.NET XML literals to define XHTML views (or any XML views).

Get the latest from SVN.

.net | html | mvc | REST | vb.net | web | xml
Sunday, November 30, 2008 10:49:44 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Wednesday, November 26, 2008

Now that the ASP.NET MVC API has settled down I decided to bring some of my ideas about REST and resource-oriented programming to it.

The following screencast shows my current prototype in action:
http://www.aboutcode.net/screencasts/snooze-aspnet-mvc.wmv

I'm keen for comments and feedback.

The source code is currently available via SVN here:
http://svn2.assembla.com/svn/snooze/branches/aspnet

.net | c# | mvc | REST | screencast | web
Wednesday, November 26, 2008 3:23:02 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Sunday, July 13, 2008

Sending data from a resource to a view in a strongly-typed, but syntactically lightweight manner is not possible with C# or VB.NET.

So check out this screencast of the new "render" macro in NRest!

In a nutshell, my resource looks like:

[Resource("")]
public class RootResource
{
    public Get() : void
    {
        def test = 42;
        render (Foo = "Hello", Bar = "World", test);
    }
}

My VB.NET view looks like:

Public Class RootPage
    Inherits Page(Of RootPageContent)

    Public Overrides Function GetHtml() As XElement
        Return _
        <html>
            <body><%= Content.Foo %>, <%= Content.Bar %></body>
        </html>
    End Function
End Class

The RootPageContent DTO class is generated at compile time by the render macro. Everything is strongly-typed.

.net | dsl | macro | nemerle | nrest | REST | web
Sunday, July 13, 2008 3:27:17 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, July 02, 2008

This is a very quick video showing the work I've been doing with Nemerle, ASP.NET routing and VB 9 XML literals.
I'm trying to find the most efficient way to create RESTful web applications. I'm willing to use all the tools in the box and even make my own to achieve this.

.net | nemerle | REST | screencast | vb.net
Wednesday, July 02, 2008 11:19:24 AM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [1]  | 
# Thursday, January 10, 2008

I have released an initial version of Snooze. http://www.assembla.com/wiki/show/snooze

Snooze is an REST framework for ASP.NET. It puts the emphasis back on the "R" of URI. The Resource concept is a first-class citizen.

In Snooze you create a resource class that defines the URI template and HTTP methods it supports.

[HttpResource("customer/{CustomerId}")] // Defines the URI template for this resource
public class CustomerResource : HttpResource // A useful base class that implements IHttpResource
{
    // URI template variables are mapped to properties
    public int CustomerId { get; set; }

    // Handles the HTTP GET method
    public override void Get()
    {
        RenderView("Customer", Data.Customers[CustomerId]);
    }

    public override void Put()
    {
        // Read data sent in Request body and update the customer...
    }

    public override void Delete()
    {
        // Delete the customer...
    }

    // HTTP POST can also be provided if it makes sense for the resource.
}

This will mean a URI like "http://yourserver.com/customer/42" will invoke the Get method of an instance where CustomerId equals 42.

What about creating a new Customer?

Well you don't have an ID for the new customer since that is probably created in the database. Therefore you don't know what the URI will be yet. The correct solution here is to POST the new customer data to a CustomerList resource, with URI "/customers".

Alternative GET Views

You can create extra GET methods:

[HttpGetView("edit")]
public void GetEdit()
{
    RenderView("CustomerEdit", Data.Customers[CustomerId]);
}

This results in URIs like "/customer/42?edit"

File Extensions

To support different file formats, such as XML and JSON use:

[HttpGetFile(".xml")]
public void GetEdit()
{
    SendXml(Data.Customers[CustomerId]);
}

This will be mapped to by URIs like /customer/42.xml

Sub-Resources

Resources can be naturally nested. For example, a Customer may have Orders.

[HttpSubResource(typeof(CustomerResource), "order/{OrderId}", true)]
public class OrderResource : HttpSubResource<CustomerResource>
{
    public int OrderId { get; set; }
    // ...
}

In this sub-resource, you can have access the parent CustomerResource, using the strongly-typed, ParentResource property.

URIs for this sub-resource will look like: "/customer/42/order/123"

The "true" argument in the attribute, specifies that parent query string parameters are added to this sub-resource URI as well. So a parent with URI template "customer/{CustomerId}?foo={Foo}" will yield sub-resource URI template "/customer/{CustomerId}/order/{OrderId}?foo={Foo}".

Nullable Resource Properties

Imagine a blog posts resource. Its URI could be /posts/{Year}/{Month}/{Day} to get all the posts on a given date. Now what if you want to naturally get the posts for a whole month, year, or ever?

By declaring the properties as nullable, e.g. "int?" in C#, Snooze will also map the "reduced" URIs to your class. You can then test the properties for "null" and return data accordingly.

Reusing Resource URIs

When rendering an HTML view it is likely you will need to link to other resources. Instead of manually typing the URI string, you can call the Uri property available on HttpResource.

new CustomerResource { CustomerId = 42 } .Uri

Resource Areas

Snooze supports resource "areas". These let you map all the resources of a given assembly into a given sub-path. If, for example, a third-party blogging package was built using Snooze you could include it as follows:

web.config:

<configuration>
  <restAreas>
    <area path="" assembly="MyWebsiteAssembly"/>
    <area path="blog" assembly="SomeCompany.BlogEngine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
  </restAreas>

So the blog resource URIs would look something like: http://mysite.com/blog/posts/2007/01

HTML Form Support

HTML forms only support GET and POST. To overcome this limitation you can include: <input type="hidden" name="__method" value="DELETE" /> to override the name of the HTTP method used by Snooze.

Feedback

This project came mostly out of curiosity! I wanted to see if REST could be done better under ASP.NET. The code is still very new (less than two days!) It is open source (BSD license) and available via SubVersion. A quick sample project is also provided.

Let me know what you think. Everything is open to changes. Join the assembla project if you would like to contribute your help.

.net | c# | programming | REST | web
Thursday, January 10, 2008 9:42:04 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Monday, December 24, 2007

This is just a quick thought that came to me whilst making coffee this morning...

REST places focus on nouns (resources) in a system. Whereas it seems web services are more concerned with verbs. A service is a collection of operations. The data is passed to and from operations as messages.

Now both approaches have their merits. What strikes me as strange is our choice of programming languages when attempting to implement the aforementioned architectural styles. Object orientated programming is all about nouns (classes). Functional programming is all about verbs (functions).

I know that there is way more to web services than just a bunch of operations (because that would be simply RPC right?). However, my point is that surely OOP is ideally suited to describing a set of resources as required by a RESTful design.

Monday, December 24, 2007 9:44:48 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Sunday, December 23, 2007

I am yet to play with the new ASP.NET MVC framework. However, I am spending time reading around the area to see if it will benefit me to get more involved.

A concern that came to mind when researching is the claims of it enabling a RESTful approach to web programming. Whilst this may be true, all the examples so far seem contrary to REST. My limited understanding of REST says that URLs represent a Resource. How is http://www.mysite.com/customers/delete/42 a resource?!

Yet that is indeed the format of URL we are being shown by Scott Guthrie and others. It makes ASP.NET MVC look more like another RPC system, just with parameters encoded into the address instead of message body.

So is it possible to specify a resource URL and then a number of HTTP verbs that can execute against it? It probably is, given the extensibility of ASP.NET MVC's architecture. However, one may ask, should I be hacking this into the framework? Would the end result look anything like the original MVC code at all? Probably not!

Is it time for a real REST framework built on top of ASP.NET? I think it is!

It needs to be Resource centered. It needs to fully leverage the rich feature set of HTTP, not just GET and POST! And just to be awesome, it needs to have a client-side story too. Real REST relies on the client-side to store state. Could this be Silverlight, or do we still want JavaScript? (I'm up for cross compiling to JS from C# or MSIL!)

.net | programming | REST | ria | thinking | web
Sunday, December 23, 2007 4:02:00 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [5]  |