# Saturday, October 10, 2009

Thanks to everyone who left encouraging comments on my previous post about a new CMS I’ve created.

I have decided that I will be open sourcing the project. However I now need a snappy name for it. Naming is so hard for some reason!

Any ideas are greatly appreciated. The CMS is light-weight, very simple, runs on asp.net mvc and has plenty of ajax goodness.

.net | cms | mvc | oss | web
Saturday, October 10, 2009 6:24:40 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Thursday, October 08, 2009

Over the course of a couple of website developments I created a simple content management system. I know there are loads our there already, but I wanted something simple and easy for non-techie users. It runs on ASP.NET MVC, has an elegant extensibility model and produces clean HTML 5. I very happy with it and plan to use it on all upcoming simple websites.

The system is file based, so no SQL database is needed. This makes it ideal for running in shared hosting. It’s perfect for the ~10 page website. But there’s no reason it can’t scale up to larger sites too.

So I’m obviously enamoured with my own work :) but is it worth sharing? I would love to get the code out there for people to poke at. However, is it really worth my time doing so – setting up a project, documentation etc? My recent open sourced work seems to have taken off like a lead balloon (Snooze, Hasic, etc)! Do you want to see my new CMS? Or shall I just keep it to myself?

.net | c# | cms | mvc | web
Thursday, October 08, 2009 3:55:37 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [5]  | 

Hasic is a kick-ass view engine for ASP.NET MVC, with a completely different approach. It uses VB.NET's XML literals instead of nasty strings like most other view engines.

That's right, VB! If you are already closing your web browser upon reading that then shame on you. I'm not saying your whole app is in VB, just the views.

Using VB means this stuff comes for free:

  • Syntax colouring
  • Full intellisense in Visual Studio
  • Compiled views
  • Extensibility using regular CLR classes, functions etc

I’m looking for feedback. So please try out Hasic and let me know what you think – thanks!

.net | mvc | vb.net | web
Thursday, October 08, 2009 3:30:43 PM (GMT Daylight Time, UTC+01:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, January 19, 2009

Don't call SmtpClient.SendMail directly within your controller actions because it directly couples your controller to SmtpClient.

Don't even create an interface IMailer and wrapping implementation of this to SmtpClient.

Instead, create a new ActionResult subclass called EmailResult. Make this class have the properties From, To, Subject and BodyData. In the ExecuteResult method use the ViewEngine infrastructure to render a view of the BodyData into your own StringWriter. You can then send the resulting content via email using SmtpClient.

.net | asp | mvc | web
Monday, January 19, 2009 4:39:44 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# 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]  | 
# Monday, March 24, 2008

I've seen people testing that RenderView is called by a controller by inheriting into a "testable" controller. Madness!

RenderView is just a convenience method that calls to IViewEngine, so why not just test expectations on that with a mock? We basically want to test that the correct ViewContext is sent to the RenderView method of the view engine.

This is my test:

[TestFixture]
public class HomeControllerTests : ControllerTestsBase<HomeController>
{
    public override HomeController CreateController()
    {
        return new HomeController();
    }

    [Test]
    public void Renders_Index()
    {
        var render = ExpectRenderView();

        Controller.Index();

        Assert.That(render.Data.ViewName, Is.EqualTo("Index"));
    }
}

I don't think we can get more straight forward than that!

This is my test base class:
(I'm using Moq as the mock framework.)

public abstract class ControllerTestsBase<T>
    where T : Controller
{
    public T Controller;
    public Mock<IViewEngine> ViewEngine;

    [SetUp]
    public virtual void SetUp()
    {
        Controller = CreateController();
        ViewEngine = new Mock<IViewEngine>();
        Controller.ViewEngine = ViewEngine.Object;

        Controller.ControllerContext = new Mock<ControllerContext>(new Mock<HttpContextBase>().Object, new RouteData(), Controller).Object;
    }

    public abstract T CreateController();

    public RenderCall<ViewContext> ExpectRenderView()
    {
        var render = new RenderCall<ViewContext>();
        ViewEngine.Expect(v => v.RenderView(It.IsAny<ViewContext>()))
            .Callback(new Action<ViewContext>(render.Set));
        return render;
    }
}

The RenderCall class provides a place to receive the view context that is passed.

public class RenderCall<T>
{
    bool _called;
    T _data;

    public T Data
    {
        get
        {
            if (!_called) throw new InvalidOperationException("View was not rendered.");
            return _data;
        }
    }

    public void Set(T data)
    {
        _data = data;
        _called = true;
    }
}

.net | mvc | thinking | web
Monday, March 24, 2008 4:08:16 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |