views:

23

answers:

2

Many of my model object inherit from a class called AuditedEntity that tracks the changes to the object. I would like to have my model objects that inherit from AuditedEntity automatically have the appropriate fields populated when constructed during the model binding process. I have been looking into sub-classing the default model binder, but without much luck.

Can anyone point me in the correct direction?

+1  A: 

Are these properties are populated with known values, or values from a good source. Or are these properties populated with values dependant on values from form/route/query etc?

Subclassing the DefaultModelBinder should be fine, e.g.:

public class MyModel
{
  public string Forename { get; set }

  public string SomeSpecialProperty { get; set; }
}

public MyModelBinder : DefaultModelBinder
{
  public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
  {
    var model = (MyModel)base.BindModel(controllerContext, bindingContext);

    model.SomeSpecialProperty = // Do something here...

    return model;
  }
}

ModelBinder.Binders[typeof(MyModel)] = new MyModelBinder();

What have you found so far?

Matthew Abbott
Thanks for your answer. I actually figured it out. I also realized that I didn't clarify my question well. Thanks for your answer, I had some additional requirements, so I will post my solution below, but award you the answer.
sanbornc
A: 

I ended up having to rely on all the data having been bound. This was the solution I ended up using. placing the code in OnModelUpdated allowed me to rely on the other properties having been set.

public class AuditedEntityModelBinder : DefaultModelBinder
{

    protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        if (bindingContext.ModelType.IsSubclassOfGeneric(typeof(AuditedEntity<>)))
        {
            string name = controllerContext.HttpContext.User.Identity.Name;

            if(!name.IsNullOrEmpty())
            {
                if((bool) bindingContext.ModelType.GetProperty("IsNew").GetValue(bindingContext.Model, null))
                {
                    bindingContext.ModelType.GetProperty("CreatedBy").SetValue(bindingContext.Model, name, null);
                    bindingContext.ModelType.GetProperty("Created").SetValue(bindingContext.Model, DateTime.Now, null);
                }
                else
                {
                    bindingContext.ModelType.GetProperty("ModifiedBy").SetValue(bindingContext.Model, name, null);
                    bindingContext.ModelType.GetProperty("Modified").SetValue(bindingContext.Model, DateTime.Now, null);
                }

            } 
        }

        base.OnModelUpdated(controllerContext, bindingContext);
    }
}
sanbornc