ASP.NET MVC: получить значения из динамических контролов
От: kirillmager  
Дата: 03.03.17 11:59
Оценка:
Добрый день!
На MVC странице часть контролов создаются динамически (например из БД). Все такие контролы наследуются от абстрактнго базового класса ControlViewModel. С отображением контролов на странице проблем нет. Хотелось бы обрабатывать в контроллере по кнопке данные, введенные пользователем в эти контролы. Проблема в том, что выбрасывается исключение System.MissingMethodException: Cannot create an abstract class.

Ошибка, как я понимаю, в переопределенном методе CreateModel в классе ControlModelBinder (наследуется от DefaultModelBinder). Что вообще надо там писать, чтобы получть текущюю модель?

Делаю так:
1. Форма
@using (Html.BeginForm())
{
    for (int i = 0; i < Model.Controls.Length; i++)
    {
        if (Model.Controls[i].Visible)
        {
            <div>
                @Html.HiddenFor(x => x.Controls[i].Type)
                @Html.HiddenFor(x => x.Controls[i].Name)
                @Html.EditorFor(x => x.Controls[i])
            </div>
        }
    }
    @Html.Button(settings =>
    {
        settings.Name = "ButtonSave";
        settings.UseSubmitBehavior = true;
        settings.RouteValues = new { Controller = "Contr", Action = "Save" };
   }).GetHtml()
}

2. Метод контроллера указанием на свой ControlModelBinder
[HttpPost]
public ActionResult Save([ModelBinder(typeof(ControlModelBinder))]  MyModel myModel)
{
    // В это место вообще не прихожу из-за ошибки System.MissingMethodException: Cannot create an abstract class.
}

3. Модель:
public class MyModel : ModelBase
{
    public ControlViewModel[] Controls { get; set; } // Массив динамически создаваемых контролов
}

4.Классы для контролов:
public abstract class ControlViewModel
{
    public abstract string Type { get; }
    public bool Visible { get; set; }
    public string Name { get; set; }
}
public class TextBoxViewModel : ControlViewModel
{
    public override string Type
    {
        get { return "textbox"; }
    }
    public string Value { get; set; }
}

5. Свой ControlModelBinder:
public class ControlModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        object model = null;
        // что тут пписать - не понятно.

        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType());
        return model;
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.