MVC 2 UpdateModel на интерфейсе, должен ли игнорироваться ModelBinderAttribute? - PullRequest
1 голос
/ 15 июля 2010

У меня есть формы, отправляющие данные из экземпляров определенного абстрактного класса:

public abstract class IRestriction
{
    public string Name {get; set;}
    public abstract IModelBinder GetBinder();
}

Конкретный тип и PartialView определяются во время выполнения:

IRestriction restriction = (IRestriction)Activator.CreateInstance(Type.GetType(restriction.restriction_class));

Соответствующее частичное представление тогдаотображается правильно.

Когда форма отправляется обратно, тип выводится правильно и активируется одинаково.

Однако я не смог заставить UpdateModel привязаться к конкретной реализации.

Как заставить Модель привязываться к конкретному типу вместо интерфейса?

Что я пробовал:

Я установил атрибут ModelBinderAttribute для бетонакласс, но он игнорируется.

[ModelBinder(typeof(MyCustomModelBinder))]
public class ConcreteRestriction : IRestriction

Я очистил все связующие модели и добавил только связыватель из интерфейса.

Binders.Clear();
Binders.Add(item.GetType(), item.GetBinder());

Ничего из этого не работает.

Какой лучший способ выполнить то, что я пытаюсь сделать?

Является ли ModelBinderAttribute игнорируемым по ошибке?

** ---------------------- ОБНОВЛЕНИЕ ---------------------- **

HЭто решение для тех, кто борется с той же проблемой, которая сталкивается с этой проблемой.

Следующий класс наследует Controller.Унаследуйте его и вызовите UpdateModelDynamic () / TryUpdateModelDynamic ()

public class DynamicTypeController : Controller
{
    internal static bool IsPropertyAllowed(string propertyName, string[] includeProperties, string[] excludeProperties)
    {
        // We allow a property to be bound if its both in the include list AND not in the exclude list.
        // An empty include list implies all properties are allowed.
        // An empty exclude list implies no properties are disallowed.
        bool includeProperty = (includeProperties == null) || (includeProperties.Length == 0) || includeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase);
        bool excludeProperty = (excludeProperties != null) && excludeProperties.Contains(propertyName, StringComparer.OrdinalIgnoreCase);
        return includeProperty && !excludeProperty;
    }

    protected internal bool TryUpdateModelDynamic<TModel>(TModel model) where TModel : class
    {
        return TryUpdateModelDynamic(model, null, null, null, ValueProvider);
    }

    protected internal bool TryUpdateModelDynamic<TModel>(TModel model, string prefix) where TModel : class
    {
        return TryUpdateModelDynamic(model, prefix, null, null, ValueProvider);
    }

    protected internal bool TryUpdateModelDynamic<TModel>(TModel model, string[] includeProperties) where TModel : class
    {
        return TryUpdateModelDynamic(model, null, includeProperties, null, ValueProvider);
    }

    protected internal bool TryUpdateModelDynamic<TModel>(TModel model, string prefix, string[] includeProperties) where TModel : class
    {
        return TryUpdateModelDynamic(model, prefix, includeProperties, null, ValueProvider);
    }

    protected internal bool TryUpdateModelDynamic<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) where TModel : class
    {
        return TryUpdateModelDynamic(model, prefix, includeProperties, excludeProperties, ValueProvider);
    }

    protected internal bool TryUpdateModelDynamic<TModel>(TModel model, IValueProvider valueProvider) where TModel : class
    {
        return TryUpdateModelDynamic(model, null, null, null, valueProvider);
    }

    protected internal bool TryUpdateModelDynamic<TModel>(TModel model, string prefix, IValueProvider valueProvider) where TModel : class
    {
        return TryUpdateModelDynamic(model, prefix, null, null, valueProvider);
    }

    protected internal bool TryUpdateModelDynamic<TModel>(TModel model, string[] includeProperties, IValueProvider valueProvider) where TModel : class
    {
        return TryUpdateModelDynamic(model, null, includeProperties, null, valueProvider);
    }

    protected internal bool TryUpdateModelDynamic<TModel>(TModel model, string prefix, string[] includeProperties, IValueProvider valueProvider) where TModel : class
    {
        return TryUpdateModelDynamic(model, prefix, includeProperties, null, valueProvider);
    }

    protected internal bool TryUpdateModelDynamic<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IValueProvider valueProvider) where TModel : class
    {
        if (model == null)
        {
            throw new ArgumentNullException("model");
        }
        if (valueProvider == null)
        {
            throw new ArgumentNullException("valueProvider");
        }

        Predicate<string> propertyFilter = propertyName => IsPropertyAllowed(propertyName, includeProperties, excludeProperties);
        IModelBinder binder = Binders.GetBinder(model.GetType());

        ModelBindingContext bindingContext = new ModelBindingContext()
        {
            ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, model.GetType()),
            ModelName = prefix,
            ModelState = ModelState,
            PropertyFilter = propertyFilter,
            ValueProvider = valueProvider
        };
        binder.BindModel(ControllerContext, bindingContext);
        return ModelState.IsValid;
    }


    protected internal void UpdateModelDynamic<TModel>(TModel model) where TModel : class
    {
        UpdateModelDynamic(model, null, null, null, ValueProvider);
    }

    protected internal void UpdateModelDynamic<TModel>(TModel model, string prefix) where TModel : class
    {
        UpdateModelDynamic(model, prefix, null, null, ValueProvider);
    }

    protected internal void UpdateModelDynamic<TModel>(TModel model, string[] includeProperties) where TModel : class
    {
        UpdateModelDynamic(model, null, includeProperties, null, ValueProvider);
    }

    protected internal void UpdateModelDynamic<TModel>(TModel model, string prefix, string[] includeProperties) where TModel : class
    {
        UpdateModelDynamic(model, prefix, includeProperties, null, ValueProvider);
    }

    protected internal void UpdateModelDynamic<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) where TModel : class
    {
        UpdateModelDynamic(model, prefix, includeProperties, excludeProperties, ValueProvider);
    }

    protected internal void UpdateModelDynamic<TModel>(TModel model, IValueProvider valueProvider) where TModel : class
    {
        UpdateModelDynamic(model, null, null, null, valueProvider);
    }

    protected internal void UpdateModelDynamic<TModel>(TModel model, string prefix, IValueProvider valueProvider) where TModel : class
    {
        UpdateModelDynamic(model, prefix, null, null, valueProvider);
    }

    protected internal void UpdateModelDynamic<TModel>(TModel model, string[] includeProperties, IValueProvider valueProvider) where TModel : class
    {
        UpdateModelDynamic(model, null, includeProperties, null, valueProvider);
    }

    protected internal void UpdateModelDynamic<TModel>(TModel model, string prefix, string[] includeProperties, IValueProvider valueProvider) where TModel : class
    {
        UpdateModelDynamic(model, prefix, includeProperties, null, valueProvider);
    }

    protected internal void UpdateModelDynamic<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties, IValueProvider valueProvider) where TModel : class
    {
        bool success = TryUpdateModelDynamic(model, prefix, includeProperties, excludeProperties, valueProvider);
        if (!success)
        {
            string message = String.Format("The model of type '{0}' could not be updated.", model.GetType().FullName);
            throw new InvalidOperationException(message);
        }
    }

}

1 Ответ

3 голосов
/ 15 июля 2010

Я думаю, что это ошибка, но команда ASP.NET MVC не согласна . Привязка модели рассматривает статический тип модели во время компиляции. Мне это не нравится, но так оно и есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...