Бета-версия Asp.Net MVC: предыдущая RouteData переопределяет текущую RouteData?

У меня есть что-то похожее на следующий метод:

    public ActionResult Details(int id)
    {
        var viewData = new DetailsViewData
        {
            Booth = BoothRepository.Find(id),
            Category = ItemType.HotBuy
        };
        return View(viewData);
    }

и следующий маршрут:

routes.MapRoute("shows","shows/{controller}/{action}/{id}", new {id = 0});

До Беты все работало нормально, когда у меня был Preview 3. Теперь метод будет корректно заполнять id при первом выполнении действия. Однако во второй раз ModelState контроллера содержит значение идентификатора последнего использования. Это заставляет ActionInvoker использовать его в параметре метода вместо значения Route.

Итак, если я дважды вызываю действие для двух разных объектов, результаты будут такими:

www.mysite.com/shows/Booth/Details/1  => Details(1)
www.mysite.com/shows/Booth/Details/2  => Details(1)  //from ModelState["id"]

Из моего быстрого сканирования с помощью Reflector кажется, что сначала параметры привязываются к ModelState, а затем к Routes. Тем не менее, я никогда даже не публиковал ничего от модели. Насколько я могу судить, ModelState не должен ничего содержать.

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

РЕДАКТИРОВАТЬ: я обнаружил, что эта проблема на самом деле является симптомом того, что кажется ошибкой с DefaultValueProvider, если вы создаете экземпляр контроллера из контейнера IoC, который существует на протяжении всего времени существования приложения Asp.Net. Что происходит, так это то, что DefaultValueProvider использует Первый ControllerContext передается контроллеру и никогда не обновляет его до тех пор, пока контроллер не будет воссоздан. Это приводит к тому, что старые RouteData используются для параметров метода вместо текущих RouteData.


person Gilligan    schedule 21.10.2008    source источник
comment
Не могли бы вы отметить один из ответов ниже как ответ, чтобы я не продолжал отвечать на этот вопрос. :П   -  person Haacked    schedule 01.02.2009


Ответы (4)


Мне трудно сказать, что вы ожидаете, и что происходит из вашего поста. Возможно ли, что в вашем методе BoothRepository.Find есть ошибка, из-за которой он каждый раз возвращает одно и то же?

ModelBinder не должен влиять на этот метод, поскольку параметр метода действия имеет простой тип, int.

Были ли оба эти запроса запросами GET? Если у вас все еще есть проблемы, можете ли вы попытаться создать простейшую возможную копию и отправить ее по электронной почте в philha - microsoft dot com?

РЕДАКТИРОВАТЬ: проблема заключалась в том, что разработчик пытался повторно использовать поставщика значений в запросах (за счет того, что Castle Windsor управлял жизненным циклом контроллеров). В настоящее время нет поддержки повторного использования экземпляров контроллера в запросах, как в случае с IHttpHandler со свойством IsReusable. В общем, повторное использование контроллеров в запросах требует от вас гораздо больше работы. :)

person Haacked    schedule 21.10.2008
comment
Это не ошибка в репо. Репозиторий напрямую с Rhino.Commons. Я точно указал на GetParameterValue(ParameterInfo) actionInvoker. Я пошлю вам barebone-версию, когда у меня будет время. Спасибо за ответ. - person Gilligan; 21.10.2008
comment
Кроме того, да, оба эти запроса были GET. Вот почему я в замешательстве? Я думал, что ModelState будет заполняться только при неудачных POSTS. - person Gilligan; 21.10.2008
comment
Я считаю, что он может быть заполнен, если вы передадите недопустимый параметр методу действия даже в запросе GET. Например, если был передан id=ABC, но id является целым числом. - person Haacked; 22.10.2008
comment
Я трижды проверил веб-страницу, и никаких входных данных с идентификатором не существует. Это также происходит с обычным POST. Основная причина, по-видимому, заключается в том, что DefaultValueProvider удерживает устаревший ControllerContext. Его контекст не соответствует текущему ControllerContext контроллера. - person Gilligan; 22.10.2008

Проблема заключается в LifeStyle, я полностью упустил из виду тот факт, что он определялся, что означает, что по умолчанию контроллеры будут использовать стиль жизни Singleton. Установка LifeStyle на Transient для всех контроллеров решит эту проблему.

person Chris Canal    schedule 29.10.2008
comment
Это на самом деле решение, которое я выбрал в конце. - person Gilligan; 30.10.2008

если вы используете spring.net, измените синглтон контроллера на «false»

person Community    schedule 01.02.2009

Это распространенная проблема при использовании поведения Singleton с контейнером IoC, таким как Spring.NET или Windsor. Контроллеры не должны иметь одноэлементного поведения, поскольку ControllerContext создается для каждого запроса, как и HttpContext.

person Haacked    schedule 01.02.2009