Asp.Net MVC Beta: предыдущие данные RouteData перекрывают текущие данные RouteData - PullRequest
1 голос
/ 21 октября 2008

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

    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. Теперь метод правильно заполнит идентификатор при первом выполнении действия. Однако во второй раз контроллер 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 и причин, по которым это происходит, приветствуется.

EDIT: Я обнаружил, что эта проблема на самом деле является признаком того, что кажется ошибкой в ​​DefaultValueProvider, если вы создаете экземпляр Controller из контейнера IoC, который существует на протяжении всего времени жизни приложения Asp.Net. В этом случае DefaultValueProvider использует первый ControllerContext передается контроллеру и никогда не обновляет его, пока контроллер не будет воссоздан. Это приводит к тому, что старые данные RouteData используются для параметров метода вместо текущих данных RouteData.

Ответы [ 4 ]

1 голос
/ 29 октября 2008

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

1 голос
/ 21 октября 2008

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

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

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

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

0 голосов
/ 01 февраля 2009

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

0 голосов
/ 01 февраля 2009

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

...