Кажется, не получается заставить IncludeProperties работать над UpdateModel в ASP.NET MVC - PullRequest
6 голосов
/ 30 июля 2009

Кому-нибудь повезло с этим?

Пожалуйста, дайте мне знать, если я правильно понимаю, если у меня есть простая модель, скажем, с:

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" });

Должно ли это ТОЛЬКО обновить свойства имени и сведений? Потому что, скажем, в «создан» уже была дата из db, когда я делаю вышеизложенное, мне кажется, что для моей даты создания установлено 01-01-0001 из оригинала.

Более того, когда я тогда пытаюсь явно исключить это поле с помощью:

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

Он все еще устанавливается на 01-01-0001. Это ошибка или странная вещь, которую я делаю неправильно?

Что я действительно хочу сделать, это обновить свойства моей модели, для которых есть соответствующие поля формы, но оставить остальные из них в покое, которые были установлены из выборки db, и не устанавливать их в null или по умолчанию, что что он сейчас делает.

Я скажу, хотя, возможно, единственное различие между вышеизложенным и моим реальным сценарием состоит в том, что я использую updateModel в списке, поэтому я эффективно получаю listFromDb (parentId), а затем применяю updateModel (myList, "ListPrefix") в то, что забирает каждый элемент по [0], [1] и т. д. ... Работает, так как все имена обновляются, а все остальное - нет.

Обновление: я только что понял, что, вероятно, «includeProperties» должен определять, какие свойства вы хотите включить в форму, подобно тому, как работает связывание. Если это * так *, то как я могу сказать ему, чтобы вместо него обновлялись только определенные свойства модели?

1 Ответ

1 голос
/ 30 июля 2009

Я изучал это с помощью 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 похож на то, что он, кажется, создает новые элементы для типов коллекций.

Я попытаюсь проанализировать это позже.

...