代码之家  ›  专栏  ›  技术社区  ›  jwsample

接口上的MVC 2 UpdateModel,是否应忽略ModelBinderAttribute?

  •  1
  • jwsample  · 技术社区  · 15 年前

    我有一些表单,这些表单发布了特定抽象类实例的数据:

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

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

    然后正确渲染相应的局部视图。

    当表单被发回时,类型被正确推断并以相同的方式激活。

    但是,我还不能让UpdateModel绑定到具体的实现。

    我尝试过的事情:

    我已经在具体类上设置了ModelBinderAttribute,但是它被忽略了。

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

    我已经清除了所有的modelbinder,只从接口添加了binder。

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

    这些都不管用。

    ModelBinderAttribute是否被错误地忽略?

    **-------------------------更新----------------------**

    这里有一个解决方案,任何其他人与同一个问题谁碰巧遇到这个。

    以下类继承控制器。继承它并调用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 回复  |  直到 15 年前
        1
  •  3
  •   Craig Stuntz    15 年前

    I think it's a bug, but the ASP.NET MVC team disagrees . 模型绑定查看模型的静态编译时类型。我不喜欢,但事实就是这样。