Привязка модели ASP.NET к базовому типу

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

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

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

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

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

if (!TryUpdateModel(viewModel, form))

Я думаю, что это как-то связано с DefaultModelBinder, использующим BaseOutputViewModel для привязки ключей FormCollection к - он не содержит "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, но я думаю, что, поскольку я даю связующему экземпляр модели для работы, CreateModel никогда не вызывается. Используется Reflector в Mvc DLL, есть "BindComplexModel", которая вызывает CreateModel, только если модель является нулевой:

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

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

ура

1 ответ

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

<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 правильно рассматривал мою модель как комплекс, успешно связывающий свойства в моем производном типе!

ура

Другие вопросы по тегам