Tuesday, February 10, 2009

ARFetch for ASP.NET MVC

I'm currently in the unfortunate position of having to merge part of a MonoRail + ActiveRecord + Windsor (the full Castle stack) project with a huge existing Webforms project. I have to use existing master pages and lots of user controls, and MonoRail's support for these is rather scarce, so I thought of using ASP.NET MVC instead of trying to cram things into webforms. I already had Windsor working on the webforms project, setting up ActiveRecord is a snap, and integrating ASP.NET MVC with Windsor is a breeze thanks to MvcContrib. But I couldn't find anything to integrate ASP.NET MVC with ActiveRecord.

Luckily, MonoRail's IParameterBinder and ASP.NET MVC's IModelBinder aren't that different in spirit. In order to implement ARFetching, I only had to make a couple of minor changes to the ARFetcher and ARFetchAttribute classes.

Here's what a simple CRUD controller would look like using ARFetch:

public class PersonController : Controller {
  //
  // GET: /Person/

  public ActionResult Index() {
      return View(ActiveRecordMediator<Person>.FindAll());
  }

  //
  // GET: /Person/Details/5

  public ActionResult Details([ARFetch("id")] Person person) {
      if (person == null)
          return RedirectToAction("Index");
      return View(person);
  }

  //
  // GET: /Person/Create

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

  //
  // POST: /Person/Create

  [AcceptVerbs(HttpVerbs.Post)]
  public ActionResult Create(FormCollection collection) {
      try {
          var p = new Person();
          UpdateModel(p, collection.ToValueProvider());
          ActiveRecordMediator<Person>.Save(p);
          return RedirectToAction("Index");
      } catch {
          return View();
      }
  }

  //
  // GET: /Person/Edit/5

  public ActionResult Edit([ARFetch("id")] Person person) {
      return View(person);
  }

  //
  // POST: /Person/Edit/5

  [AcceptVerbs(HttpVerbs.Post)]
  public ActionResult Edit([ARFetch("id")] Person person, FormCollection collection) {
      try {
          UpdateModel(person, collection.ToValueProvider());
          ActiveRecordMediator<Person>.Update(person);
          return RedirectToAction("Index");
      } catch {
          return View();
      }
  }
}

Here's the full source code, all merit goes to the Castle team, any bugs are mine:

2 comments:

developer said...

Nice job!

Would you verifiy the svn repository or post an zip file with the sample project and libs?

Thanks!

Mauricio Scheffer said...

@developer: you can svn checkout this URL: http://mausch.googlecode.com/svn/trunk/MVCActiveRecordIntegration/