我有一个奇怪的问题ASP.NET 视的对象不是正在更新 UpdateModel 当时通过了一个 formCollection. UpdateModel 似乎不可能正常工作时的对象正在更新创建的通过反映。

方案:我有一个应用程序,它拥有约50查表--中的每个包括完全相同的架构,包括典型的领域,如id、标题、说明、isactive,并createdon.而不是建立50景,我想要有一个单一的查看这可能显示数据的所有查找表。我创建了一个接口,称为IReferenceEntity和实现它在每个POCOs代表我查找表。

使用这个接口,我可以很容易填便记录从查找表。(I通过项目视通过以下。)

System.Web.Mvc.ViewPage<MyNamespece.IReferenceEntity> 

从数据库中的查看,每一件事完美的作品。

然而,当我试图更新模型后,我遇到了一些问题。

如果我明确声明对象的参考如下,每一件事完美的作品的价值观我的目的是更新有的价值观,从我的形式。因此,我然后可以更新的数据库。

AccountStatus a = new AccountStatus();

UpdateModel(a, formCollection.ToValueProvider());

不幸的是,很难编码的对象类型将完全失败的原因在于使用一个接口。

(A主要目的应用程序是要能够动态地添加新表如查表没有做任何事情"特殊"。这是通过反映上装载的集会和定位的任何这类实现一个特定的接口或基类)

我的策略是要确定的具体类型的对象在回和然后创建的一个实例类型的通过反映。(机制我用来确定种类型是有些原始的。I包括它作为一个隐藏的领域内的形式。更好的想法是值得欢迎的。)

当我创建的一个实例,使用对象的反映,通过下列任一方法,没有任何的对象是正在更新,由UpdateModel.

Type t = {Magically Determined Type}

object b = Activator.CreatorInstance(t);

UpdateModel(b, formCollection.ToValueProvider());


Type t = {Magically Determined Type}

var c = Activator.CreatorInstance(t);

UpdateModel(c, formCollection.ToValueProvider());


Type t = {Magically Determined Type}

IReferenceEntity d = Activator.CreatorInstance(t);

UpdateModel(d, formCollection.ToValueProvider());

注:我已经验证的对象,正在通过建立relection都是合适的类型。

没有任何人有任何想法,这可能是为什么发生?我有点难倒。

如果我是真的"硬",我可以创建的工厂对象,它会许多实例中的任何一个这些实体参照/查询对象。然而,这将打破应用程序的能力,允许对新的查询表,以增加和发现的透明和只是不太干净。

此外,我可以尝试所产生的实际ReferenceEntity基类而不是一个接口,但是,我怀疑这是否会使任何差别。该问题似乎是与使用反映创建目的在modelbinder.

任何帮助表示赞赏。

安东尼

有帮助吗?

解决方案

Cisco网络回答了这个关于ASP.NET 论坛。它的工作与仅仅几个小的修改。谢谢你cisco网络.


问题是,[尽量]UpdateModel方法允许指定模型使用的通用参数,唯一使他们不允许的动态模型的规范。我已经创建了发票。

你可以看到TryModelUpdate方法实现在这里。所以它不是困难的写自己的过载:

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


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

    ModelBindingContext bindingContext = new ModelBindingContext()
                                             {
                                                 Model = model,
                                                 ModelName = prefix,
                                                 ModelState = ModelState,
                                                 //ModelType = typeof(TModel), // old  
                                                 ModelType = model.GetType(),
                                                 // new  
                                                 //PropertyFilter = propertyFilter,  
                                                 ValueProvider = valueProvider
                                             };
    binder.BindModel(ControllerContext, bindingContext);
    return ModelState.IsValid;
}

其他提示

你IReferenceEntity包含制定者的性质以及吸气?我认为最后一样会的工作,如果接口有财产的制定者,但你必须把它获得它要编译。

Type t = {Magically Determined Type}

IReferenceEntity d = Activator.CreatorInstance(t) as IReferenceEntity;

UpdateModel(d, formCollection.ToValueProvider());

通常的理由是,它不会设置一个属于一类,是因为它不能找到一个公共设置器的方法可供使用经过反射。

只是一个快速的"另一件事情试试":

UpdateModel(d as IReferenceEntity, formCollection.ToValueProvider());

不知道,如果这会的工作,我还没有尝试过自己,但它的第一件事情,来铭记。

如果我得到机会后,我将看看默认的模式粘合剂码看看是否有任何东西在那里是显而易见的...

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top