Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / ASP.NET MVC. Использование абстрактного класса в качестве свойства модели / 4 сообщений из 4, страница 1 из 1
15.08.2014, 16:08
    #38721409
simlex
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASP.NET MVC. Использование абстрактного класса в качестве свойства модели
Здравствуйте! Столкнулся со следующей проблемой: у модели есть свойство, представляющее абстрактный класс (например "характеристики": для одной модели это будет H1, для другой H2 и т.д. Все они расширяют H0, который и является абстрактным).
Так вот, при редактировании модели среда не может обработать это свойство, пишет: "Невозможно создать абстрактный класс". понятно, что абстрактный класс создавать нельзя, но как тогда добавить новую модель?
...
Рейтинг: 0 / 0
15.08.2014, 22:20
    #38721624
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASP.NET MVC. Использование абстрактного класса в качестве свойства модели
simlex,

нужно реализовать "связыватель" модели:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
// специальный связыватель для абстрактного класса, который с помощью поля
// Discriminator пытается создать экземпляр конкретного класса
public class MyBaseClassBinder : DefaultModelBinder
    {
        protected virtual Object CreateModel(
            ControllerContext controllerContext,
	    ModelBindingContext bindingContext,
	    Type modelType)
        {
            // работает только для типа MyBaseClass
            if(modelType != typeof(MyBaseClass)) 
                return base.CreateModel(controllerContext, bindinfContext, modelType);

            // получить наименование конкретного типа класса
            var discriminator = bindingContext.ValueProvider.GetValue("Discriminator").RawValue as string;

            // создать экземпляр типа по имени, необходимо также указать неймспейс,
            // где эти типы лежат
            var myObj = Activator.CreateInstance("Namespace.Of.My.Models", discriminator);

            // вернуть экземпляр класса для последующего связывания
            // конечно, в настоящей реализации надо всё обернуть в try/catch, сделать
            // обработку ошибок и т.д.
            return myObj;
        }
    } 



для примера, абстрактный класс:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
// указать связыватель для класса
[ModelBinder(typeof(MyBaseClassBinder))]
public abstract class MyBaseClass
{
    ...
    здесь поля абстрактного класса
    ...

    // специальное поле, где надо сохранять тип конкретного класса, иначе
    // связытель не сможет понять экземпляр какого типа надо создавать
    public string Discriminator { get; set; }
}



как это работает. когда отдаёте модель на редактирование, запишите в поле Discriminator её конкретный тип (obj.GetType().ToString()), таким образом связыватель сможет создать этот конкретный тип во время биндинга.

можно вместо строкового наименования типа хранить и передавать специальные Enum (в поле Discriminator), что будет конечно безопасней, но в качестве обобщённого примера решения вашей задачи пойдёт и так.
...
Рейтинг: 0 / 0
15.08.2014, 22:23
    #38721625
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASP.NET MVC. Использование абстрактного класса в качестве свойства модели
уточнение:

protected virtual override Object CreateModel

конечно же
...
Рейтинг: 0 / 0
18.08.2014, 09:10
    #38722182
simlex
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
ASP.NET MVC. Использование абстрактного класса в качестве свойства модели
hVostt, спасибо большое, очень помогли!
...
Рейтинг: 0 / 0
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / ASP.NET MVC. Использование абстрактного класса в качестве свойства модели / 4 сообщений из 4, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]