# 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]  |