views:

297

answers:

3

Has anybody had luck with this?

Please let me know if I understand it correctly, if I have a simple model let's say with:

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

and then I perform a:

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

Should this ONLY update the name and detail properties? Because let's say there was a date already from db in 'created', when I do the above it seems to set my created date to 01-01-0001 from the original.

Moreover, when I then try to explicitly exclude this field with:

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

It is still being set to 01-01-0001. Is this a bug, or a strange thing I am doing wrong?

What I effectively want to do, is update my model properties for which there are corresponding form fields for, but leave the rest of them alone which were set from the db fetch alone and not set them to null or default, which is what it currently appears to be doing.

I will say though, perhaps the only difference between above and my real-world scenario is I am using updateModel on a list, so I am effectively getting listFromDb(parentId) and then applying updateModel(myList, "ListPrefix") on that which picks up each item by [0], [1] etc... It works, as all the names are updating, but everything else is not.

Update: I've just realised probably 'includeProperties' is to define which properties you wish to include from the form, similar to how the bind works. If this *is* the case, then how can I tell it to only update certain model properties instead?

+2  A: 

I'm having the same problem but only when I use collection of custom data types. http://stackoverflow.com/questions/1207991/calling-updatemodel-with-a-collection-of-complex-data-types-reset-all-non-bound-v

Marco M.
Very interesting Marco, seems we suffered the same problem. I'm a bit weary of updating the internal method, right now to achieve a solution and for flexibility, I am going back to basics and binding my FormCollection values in a foreach to respective model properties, this let's me verify all properties being updated, are properties I have set to be updated.Could be an interesting question for the ASP.NET MVC team, 'what is expected/desired behaviour'..
GONeale
+1  A: 

I've been looking into this using Reflector... the call stack is:

UpdateModel() --> TryUpdateModel() --> DefaultModelBinder.BindModel() ---> either BindComplexModel() or BindSimpleModel().

Here's the disassembly for 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;
        }
    }

It's pretty clear that there are new elements being created. I'm unclear as to the exact logic of the flags though, and I don't have time to investigate it further right now. Incidentally, BindComplexModel is similar in that it seems to be creating new elements for collection types.

I'll try to analyze it more later.

womp
Thanks for your help womp.
GONeale
Hi, I went down same route following source code to see what is going on inside there (having a lot of problems with my dropdownlists sometimes not binding depending on where selectlist comes from...).How did you do this in Reflector? Would be helpful to be able to get the call stack for a few things in MVC framework.
Jason
A: 

These properties are of structure or class?

scorpio