Note that there are some explanatory texts on larger screens.

plurals
  1. POUsing custom ModelBinder to have strongly typed TPH models in controller actions-- is this smelly?
    text
    copied!<p>Here's a little background on my solution:</p> <ul> <li>ASP.Net MVC app</li> <li>Using Linq-to-SQL with table-per-hierarchy inheritance</li> <li>Using DataAnnotationsModelBinder as default</li> </ul> <p>So I have a <code>Device</code> abstract class and then a series of derived classes (<code>ServerDevice</code>, <code>DiskDevice</code>, <code>PSUDevice</code>, etc) that inherit from it in the proscribed Linq-to-SQL way. I have one controller that handles all these different related model types, and it renders different partials based on the type and a handy drop down to select them. My (GET) Create method looks like this:</p> <pre><code>// GET: /Devices/Create/3 public ActionResult Create(int? deviceTypeID) { return View(DeviceFactory(deviceTypeID); } </code></pre> <p>Where <code>DeviceFactory</code> is a static method returns a new instance of one of the derived classes based on an int discriminator. The POST Create method looks like this:</p> <pre><code>// POST: /Devices/Create [AcceptVerbs(HttpVerbs.Post)] public ActionResult Create([ModelBinder(typeof(DeviceModelBinder))]Device device) { if (!ModelState.IsValid) return View(device); _repository.Add(device); _repository.Save(); TempData["message"] = string.Format("Device was created successfully."); return RedirectToAction(Actions.Index); } </code></pre> <p>and my custom model binder looks like this:</p> <pre><code>public class DeviceModelBinder : DataAnnotationsModelBinder { private readonly Dictionary&lt;string, Type&gt; _deviceTypes = new Dictionary&lt;string, Type&gt; { {"1", typeof (ServerDevice)}, {"2", typeof (DiskDevice)} // And on and on for each derived type }; protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { return base.CreateModel(controllerContext, bindingContext, _deviceTypes[bindingContext.ValueProvider["deviceTypeID"].AttemptedValue]); } } </code></pre> <p>So after trying to hook this up all day, reading about ActionInvoker, custom ActionFilters, and all sorts of other MVC stuff, I'm wondering if the solution I've arrived at is a good one. Help allay my fears that I'm missing some hugely obvious concept and re-inventing the wheel. <strong>Is there a better or more concise way?</strong></p> <p>Thanks!</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload