views:

43

answers:

2

My issue involves updating an entity via an edit form with a reference to another entity represented by a drop down list. I'm using ASP.NET MVC 2. Details:

Public Class Category
{
   int Id { get; set;}
   string Name { get; set}
   Category Parent { get; set}
}
  • An edit page for the category generated by EditorFor
  • Edit page contains a drop down for selecting the parent category, with name/id=Parent.Id
  • There is a 'none' entry in the drop down list with value='' (for categories with no parent).

Update process in Action:

  • Current entity retrieved from repository by id.
  • TryUpdateModel applied to retrieved entity

Problem:

When an edited category is submitted, if the dropdown is set to 'none' a new entity is being instantiated for 'parent' when it tries to update on the parent.id. This causes problems when persisting via the ORM. So, what to do in this situation? Is there any way to stop the 'parent' object from being instantiated, and leaving the parent reference null?

Thanks.

Update: I'm using NHibernate as my ORM, in case this is useful.

A: 

You could add parentId parameter to action method and check it manually and if it's null then call TryUpdateModel method with excludeProperties set to

new [] {"Parent"}
Alexander Prokofyev
I was hoping for a more general solution really. This must be a scenario faced often surely? However, perhaps I'll have to go with something like this. Thanks.
UpTheCreek
+2  A: 

Looks like a good scenario for a custom model binder:

public class CategoryModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var model = base.BindModel(controllerContext, bindingContext) as Category;
        if (model != null && model.Id == null) // adapt this test if necessary
        {
            return null;
        }
        return model;
    }
}

And in Application_Start:

ModelBinders.Binders.Add(typeof(Category), new CategoryModelBinder()); 

Also make sure that the Id property on your model is a nullable integer or the binder will crash if you try to bind it to an empty string.

Darin Dimitrov
Ah, This looks like the ticket - thanks darin.
UpTheCreek
@Darin: Is there any way of doing this without making Id nullable? I'd rather stick with a 'normal' id type if possible. I don't want to mess with the way that Nhibernate is supposed to assign id's to new object that should be stored either.
UpTheCreek
You should be using view models when working with the views and not directly working with the NHibernate entities.
Darin Dimitrov