似乎无法在ASP.NET MVC中使用UpdateModel的IncludeProperties,请问如何解决?

6

有人在这方面有好运气吗?

请告诉我是否我理解正确,如果我有一个简单的模型,例如:

public string Name { get; set; }
public string Details { get; set; }
public DateTime? Created { get; set; }

然后我执行:

var myModel = getCurrentModelFromDb(id);
UpdateModel(myModel, "ModelName", new string { "Name", "Details" });

这个操作是否只更新名称和详细信息属性?因为假设数据库中已经有了“创建时间”字段的日期,当我执行上述操作时,它似乎会将我的创建时间从原始时间更改为 01-01-0001。

此外,当我尝试使用以下方式明确排除该字段时:

UpdateModel(myModel, "ModelName", 
   new string { "Name", "Details" }, new string { "Created" });

它仍然被设置为01-01-0001。这是一个错误还是我做错了奇怪的事情?
实际上,我想要做的是更新我的模型属性,其中有相应的表单字段,但保留那些仅从数据库获取而不将它们设置为null或默认值的其余属性,这似乎是当前正在执行的操作。
尽管如此,我必须说,也许以上和我的真实场景之间唯一的区别是我正在使用列表上的updateModel,因此我实际上正在获取listFromDb(parentId),然后在其上应用updateModel(myList,“ListPrefix”),该方法通过[0],[1]等方式获取每个项目... 它能工作,因为所有名称都在更新,但其他所有内容都没有。
更新:我刚意识到“includeProperties”可能是定义您希望从表单中包括哪些属性的方式,类似于绑定的工作方式。如果确实是这种情况,那么我该如何告诉它仅更新某些模型属性呢?
1个回答

1

我一直在使用Reflector研究这个问题...调用堆栈如下:

UpdateModel() --> TryUpdateModel() --> DefaultModelBinder.BindModel() ---> 要么是BindComplexModel()要么是BindSimpleModel()

这是BindSimpleModel()的反汇编代码:

 if (bindingContext.ModelType != typeof(string))
    {
        if (bindingContext.ModelType.IsArray)
        {
            return ConvertProviderResult(bindingContext.ModelState, bindingContext.ModelName, valueProviderResult, bindingContext.ModelType);
        }
        Type type = ExtractGenericInterface(bindingContext.ModelType, typeof(IEnumerable<>));
        if (type != null)
        {
            object o = this.CreateModel(controllerContext, bindingContext, bindingContext.ModelType);
            Type collectionType = type.GetGenericArguments()[0];
            Type destinationType = collectionType.MakeArrayType();
            object newContents = ConvertProviderResult(bindingContext.ModelState, bindingContext.ModelName, valueProviderResult, destinationType);
            if (typeof(ICollection<>).MakeGenericType(new Type[] { collectionType }).IsInstanceOfType(o))
            {
                CollectionHelpers.ReplaceCollection(collectionType, o, newContents);
            }
            return o;
        }
    }

很明显有新元素正在被创建。但是我不清楚标志的确切逻辑,而且现在没有时间进一步调查它。顺便说一下,BindComplexModel也类似于为集合类型创建新元素。

我稍后会尝试更深入地分析它。


嗨,我按照相同的源代码路径进行了一些操作,以查看里面发生了什么(有时我的下拉列表绑定不起作用,这取决于选择列表来自何处...)。你是如何在Reflector中实现这个的?能够获取MVC框架中某些内容的调用堆栈将会很有帮助。 - Jason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接