views:

84

answers:

3

With NHibernate I no longer expose foreign keys on my domain objects, so Product no longer has a property:

public int CategoryId {get;set;}

but instead has:

public Category Category {get;set;}

Unforunately this doesn't appear to work so well with the automatic model binding in ASP.NET MVC - if I want to simply bind a form collection directly to my domain object.

For example, I couldn't just have a selectlist of Category Id values in my view, accept a product object in my controller action, and expect MVC to convert this into a category object.

My solution so far has been to create view models that do have properties for the foreign key values - However, this normally leads to a fair bit of duplication in code and extra mapping logic in my controller.

Is there a better way?

+6  A: 

Using pared-down view models tailored specifically for your views is the recommended approach; you can simplify the mapping operations required by using AutoMapper.

DanP
@DanP - I know this is the recommended approach but sometimes it's just not necessary. I have a simple domain object with three properties - just seems a whole lot of extra work for something so simple.
Ben
@Ben - Famous last words.. Seriously though, AutoMapper makes this trivial, once you start to encounter any sort of disconnect between your domain model and your view models you'll thank yourself for going this route...
DanP
And there's me wanting something quick and dirty :) - AutoMapper looks the best bet and based on some other solutions suggested, specific view models seems to be the cleanest approach, even on simple objects.
Ben
@Ben - I was in the same boat as you were (wanting to work directly with domain models from the view) - but as I said, as soon as there's any sort of disconnect you'll start putting more effort into workarounds than it would have been to use this approach to begin with. Not to mention everything that automapper brings to the table (have a look at custom formatters, resolvers and type converters, they save countless hours of work).
DanP
@Ben - another quick recommendation - have a look at the whocanhelpme application; the way they handle mapping is quite elegant.
DanP
+4  A: 

Also, remember that when using Nhibernate, you are dealing with proxy objects and it is best not to try and serialize them across application boundaries, like model binding, web services, or Remote calls.

If you need to turn CustomerID into Customer, you are going to have to create a Custom Model Binder that is data repository aware and can take customerID and get a Customer object. There are some cases where this is useful, but I would not recommend it for this scenario.

Agreed; we actually have 2 layers of dtos; one returned by the service layer and one used specifically for views. The service layer ones ensure the needed data is completely hydrated before crossing the service boundary.
DanP
+1  A: 

I came up with a custom model binder that I posted on a similar question: http://stackoverflow.com/questions/662651/asp-net-mvc-model-binding-foreign-key-relationship/2971105#2971105

I'm using it in a project and it's working quite well.

dave thieben