Created
April 18, 2012 18:26
-
-
Save joelpurra/2415633 to your computer and use it in GitHub Desktop.
InheritedClassModelBinder: A ModelBinder for ASP.NET MVC3 that handles creating concrete class instances mapped to an abstract superclass. Based on code by Kelly.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace JoelPurra.Web.Binders | |
{ | |
using System; | |
using System.Diagnostics.Contracts; | |
using System.Linq; | |
using System.Web.Mvc; | |
using rDoing.Scraper.Web.Mvc.Controllers.ViewModels.Binder.Helpers; | |
/// <remarks> | |
/// Based on | |
/// http://stackoverflow.com/questions/5460081/asp-net-mvc-3-defaultmodelbinder-with-inheritance-polymorphism | |
/// http://stackoverflow.com/questions/5460081/asp-net-mvc-3-defaultmodelbinder-with-inheritance-polymorphism/7517655#7517655 | |
/// http://stackoverflow.com/questions/4012217/asp-net-mvc-2-binding-to-abstract-model | |
/// http://stackoverflow.com/questions/4012217/asp-net-mvc-2-binding-to-abstract-model/7517417#7517417 | |
/// | |
/// Original by Kelly | |
/// http://stackoverflow.com/users/85802/kelly | |
/// | |
/// Edited by Joel Purra | |
/// https://gist.github.com/2415633 | |
/// </remarks> | |
public class InheritedClassModelBinder : DefaultModelBinder | |
{ | |
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) | |
{ | |
if (modelType.IsAbstract) | |
{ | |
// modelType is the abstract base class | |
// concreteModelTypeName is the concrete subclass | |
var concreteModelTypeName = ContextValueHelper.GetValue(controllerContext, bindingContext, "ModelTypeName"); | |
Contract.Assert(concreteModelTypeName != null, "View does not contain ModelTypeName"); | |
var type = modelType.Assembly.GetTypes().SingleOrDefault(x => x.IsSubclassOf(modelType) && x.Name == concreteModelTypeName); | |
Contract.Assert(type != null, "Invalid ModelTypeName"); | |
var instance = bindingContext.Model ?? base.CreateModel(controllerContext, bindingContext, type); | |
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => instance, type); | |
return instance; | |
} | |
return base.CreateModel(controllerContext, bindingContext, modelType); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In case you see the reference to
SharpArch.Web.Mvc.ModelBinder
in any of the revisions it's because I'm usingSharpModelBinder
as a base class in my local version.