ModelBinder не вызывается - PullRequest
       27

ModelBinder не вызывается

3 голосов
/ 02 апреля 2011

За мой предыдущий вопрос , я реализовал модель подшивки, которая отображает /api/v1/widgets/1,2,3 в

// WidgetsController.cs: 
public ActionResult Show(IEnumerable<int> idArgs)
{

}

Это работало какое-то время, но теперь это уже не так. Мой ModelBinder даже не вызывается вообще. Когда мое действие вызывается, idArgs имеет значение пустого списка, даже если я установил его значение по умолчанию null в маршруте, что предполагает мне, что связыватель модели по умолчанию думает, что откуда-то получает значение. Единственное изменение, которое я сделал с прошлой недели, когда оно работало, заключается в том, что ранее я называл свое действие ShowMany. С тех пор я переименовал его в Show. Может кто-нибудь помочь мне понять, почему мой ModelBinder не вызывается?

В global.asax.cs у меня есть

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);
    ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());

    ModelBinders.Binders.Add(typeof(IEnumerable<int>), new IEnumerableOfIntCSVModelBinder());
}

И маршрут выглядит следующим образом (я убедился, что этот маршрут используется):

context.MapRoute(
    "show",
    "api/{controller}/{idArgs}",
    new { action = "show" },
    new { httpMethod = new HttpMethodConstraint("GET"), idArgs = @"^(\d+,)+\d+,?$" }
);

Редактировать: Я попробовал еще немного поработать с маршрутами, а также закомментировать JsonValueProvider, и я все еще получаю пустой массив. В моем контроллере я могу сделать

var ids = RouteData.Values["idArgs"];

и получите строку «1,2,3». Если бы только Framework передавал это моему ModelBinder, мой ModelBinder превратил бы его в IEnumerable.

Я использую AutoFac. Возможно ли, что AutoFac внедряет пустой массив в мой метод контроллера? У меня не было таких проблем в других местах (и мы везде используем AutoFac в этом проекте).


Edit2 : я также пытался украсить как параметр действия idArgs, так и контроллер с [ModelBinder(typeof(IEnumerableOfIntCSVModelBinder))], но это не дало эффекта.

Ответы [ 2 ]

1 голос
/ 02 апреля 2011

Я вижу, что в вашем Application_Start добавлено JsonValueProviderFactory. Может быть, в реализации этой фабрики есть что-то, что предотвращает попадание подшивки модели?

Также указанный вами URL /api/v1/widgets/1,2,3 не имеет отношения к определению маршрута, которое у вас есть "restapi/{controller}/{idArgs}".

0 голосов
/ 16 апреля 2011

Не могли бы вы попробовать перенести свой маршрут, чтобы стать первым зарегистрированным? Я просто попытался написать код, и у меня возникла проблема, когда мой маршрут не работал, пока я не переместил его регистрацию выше регистрации маршрута по умолчанию. Маршруты выполняются в том порядке, в котором они зарегистрированы, поэтому, если у вас есть более конкретная регистрация после и более общая регистрация, она может не сработать.

В этом примере второй маршрут никогда не вызывается:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional });

routes.MapRoute(
    "Ids",
    "{controller}/{action}/{ids}",
    new { controller = "Home", action = "Index", ids = UrlParameter.Optional },
    new { ids = @"^(\d+,)+\d+,?$" });

Но если вы измените их порядок, будет вызван "Ids".

...