Вот небольшая предыстория моего решения:
- Приложение ASP.Net MVC
- Использование Linq-to-SQL с наследованием таблиц на иерархию
- Использование DataAnnotationsModelBinder по умолчанию
Итак, у меня есть Device
абстрактный класс, а затем серия производных классов (ServerDevice
, DiskDevice
, PSUDevice
и т. Д.), Которые наследуются от него в запрещенном способе Linq-to-SQL. У меня есть один контроллер, который обрабатывает все эти различные связанные типы моделей, и он отображает различные партиалы в зависимости от типа и удобный выпадающий список для их выбора. Мой (GET) метод Create выглядит следующим образом:
// GET: /Devices/Create/3
public ActionResult Create(int? deviceTypeID)
{
return View(DeviceFactory(deviceTypeID);
}
Где DeviceFactory
- статический метод, возвращающий новый экземпляр одного из производных классов на основе целевого распознавателя. Метод POST Create выглядит следующим образом:
// 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);
}
и моя пользовательская модель переплета выглядит так:
public class DeviceModelBinder : DataAnnotationsModelBinder
{
private readonly Dictionary<string, Type> _deviceTypes =
new Dictionary<string, Type>
{
{"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]);
}
}
Итак, после попыток подключить это весь день, читая о ActionInvoker, пользовательских ActionFilters и всевозможных других вещах MVC, я задаюсь вопросом, является ли решение, к которому я пришел, хорошим. Помогите развеять мои страхи, что я упускаю какую-то чрезвычайно очевидную концепцию и заново изобретаю колесо. Есть ли лучший или более лаконичный способ?
Спасибо!