Привязка модели ASP.NET к базовому типу - PullRequest
1 голос
/ 31 октября 2010

У меня есть BaseViewModel, все мои модели просмотра наследуются.

public class MagazineViewModel : BaseOutputViewMode
{
    public string TitleOfPublication { get; set; }
}

В моем контроллере я использую фабричный метод для возвращения корректного View Model на основе ввода:

// e.g. viewModel contains an instance of MagazineViewModel 
BaseOutputViewModel viewModel = BaseOutputViewModel.GetOutputViewModel(output);

Когда я использую TryUpdateModel, чтобы попытаться связать с FormCollection, которыйЯ знаю, что содержит ключ "TitleOfPublication", он никогда не устанавливается в моей модели представления:

if (!TryUpdateModel(viewModel, form))

Я думаю, что это как-то связано с DefaultModelBinder, использующим BaseOutputViewModel для привязки ключей FormCollection - он не содержитa "TitleOfPublication", производный от MagazineViewModel.

Я пытаюсь свернуть свою собственную привязку модели, чтобы переопределить поведение BindModel DefaultModelBinder.Все подключено правильно, и я могу отладить его сразу после вызова TryUpdateModel:

 public class TestModelBinder : DefaultModelBinder, IFilteredModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        // Tried the following without success ....
        // 1. Quick hardcoded test
        // bindingContext.ModelType = typeof(MagazineViewModel);
        // 2. Set ModelMetadata, hardcoded test again
        // bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(MagazineViewModel));
        // 3. Replace the entire context
        // ModelBindingContext context2 = new ModelBindingContext();
        // context2.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, typeof(MagazineViewModel));
        // context2.ModelName = bindingContext.ModelName;
        // context2.ModelState = bindingContext.ModelState;            
        // context2.ValueProvider = bindingContext.ValueProvider;
        // bindingContext = context2;
    }
}

Но я не уверен, как работать с bindingContext?Что необходимо обновить, чтобы я мог указать DefaultModelBinder связываться, используя производные свойства View Model?Или я просто совершенно неправильно понял это!

Я попытался переопределить CreateModel - очень похоже на DerivedTypeModelBinder в MvcContrib, но я думаю, что, поскольку я даю binder экземпляр модели для работы, CreateModelникогда не звонил.При использовании Reflector в Mvc DLL появляется «BindComplexModel», который вызывает CreateModel только в том случае, если модель имеет нулевое значение:

if (model == null)
{
    model = this.CreateModel(controllerContext, bindingContext, modelType);
}

Любые указатели получены с большим удовольствием!

Приветствия

1 Ответ

1 голос
/ 01 ноября 2010

ОК - наконец-то дошло до этого!На самом деле с моим механизмом связывания не было ничего плохого, проблема в конечном итоге привела к появлению пары входных тегов, которые не имели имени / идентификатора:

<input id="" name="" type="text">

Суть этого теста в DefaultModelBinder:

// Simple model = int, string, etc.; determined by calling TypeConverter.CanConvertFrom(typeof(string))
// or by seeing if a value in the request exactly matches the name of the model we're binding.
// Complex type = everything else.
if (!performedFallback) {
     ValueProviderResult vpResult =
            bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
            if (vpResult != null) {
                return BindSimpleModel(controllerContext, bindingContext, vpResult);
            }
        }

Без идентификатора / имени коллекция форм имеет ключ «», что означает, что GetValue правильно вернул значение для этого поля, продолжая связываться как простая модель.

КогдаИдентификатор / имя добавлены, коллекция форм не содержит ключа «» (теперь это имя моей модели, так как мы используем TryUpdateModel).Это означало, что DefaultModelBinder правильно рассматривал мою модель как комплекс, успешно связывающий свойства в моем производном типе!

Cheers

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...