Пользовательский ModelBinder MVC 3 не используется

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

OfferId=3802&DeliveryDate=11%2F02%2F2011&DeliveryTime=12%3A00&location=1&location=698

Он отправляет его в действие MVC:

[HttpPost]
public ActionResult DeliveryOptions(DeliveryOptions model)
{
    ...
}

Модель DeliveryOptions выглядит следующим образом:

public class DeliveryOptions
{
    public long? OfferId { get; set; }

    [CustomValidation(typeof(CustomValidator), "IsDeliveryDateValid")]
    public DateTime? DeliveryDate { get; set; }

    public DateTime? DeliveryTime { get; set; }

    [CustomValidation(typeof(CustomValidator), "IsLocationsValid")]
    public OfferLocations Locations { get; set; }
}

Теперь я хотел бы проанализировать размещенные переменные location в объекте OfferLocations, который выглядит следующим образом:

[ModelBinder(typeof(OfferLocationsModelBinder))]
public class OfferLocations
{
    [Required]
    public int[] LocationIds { get; set; }
}

Связующая модель в настоящее время выглядит так:

public class OfferLocationsModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        throw new NotImplementedException();
    }
}

Проблема в том, что я не могу сломать NotImplementedException. Связыватель модели не выполняется. Я, вероятно, пропустил что-то очевидное; Любые идеи?


person Edgar    schedule 11.02.2011    source источник


Ответы (3)


Попробуйте унаследовать связыватель модели от System.Web.Mvc.DefaultModelBinder и переопределите метод object BindModel(ControllerContext, ModelBindingContext). Посмотрите, работает ли это. Если это так - вы можете работать оттуда :)

Это то, что я делаю прямо сейчас. По сути, я должен был убедиться, что если в запросе приходит конкретный тип — метод выполняется против этого значения. Регистрационный код связывателя модели точно такой же — атрибут, применяемый к классу свойства.

Связующая модель выглядит следующим образом:

public class TableModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var result = base.BindModel(controllerContext, bindingContext) as ITableModel;
        if (result != null)
            result.UpdateSorter();
        return result;
    }
}

P.S. Получение от связывателя базовой модели дает мне дополнительное преимущество привязки всех свойств с использованием стандартного кода Mvc, и затем я могу расширить десериализованный объект :)

Надеюсь это поможет

person Artiom Chilaru    schedule 11.02.2011
comment
Использовал этот метод в моем обходном пути. Сработало отлично, потому что я изменил опубликованную переменную на строку CSV. - person Edgar; 14.02.2011

Зарегистрирован ли этот ModelBinder в DepedencyResolver? Интересно, есть ли у MVC проблемы с поиском вашего ModelBinder и он возвращается к стандартному.

person neontapir    schedule 11.02.2011
comment
Я попытался зарегистрировать связыватель модели в Global.asax Application_Start, но это не помогло. Кроме того, в проекте есть несколько других пользовательских биндеров моделей, которые очень похожи на мои, и они работают. Я просто не могу понять, почему мой не работает. Нужно ли мне переименовывать переменные поста location во что-то другое? - person Edgar; 11.02.2011

Не удалось заставить это работать. Пришлось реализовать обходной путь.

Теперь я публикую идентификаторы местоположений в виде строки CSV, и они подбираются настраиваемой привязкой модели, поэтому их можно проанализировать в массиве. Жаль, что я не мог сделать это по-другому.

person Edgar    schedule 11.02.2011