Значения необязательных параметров T4MVC, подразумеваемые из текущего контекста

Я заметил, как мне кажется, странное поведение с T4MVC. В частности, я пытаюсь создать ActionLink (используя HtmlHelper) для действия, где значение необязательного параметра равно null. Это отлично работает большую часть времени. Однако, если текущий маршрут совпадает с тем, для которого строится ActionLink, И опциональный параметр имеет ненулевое значение, результирующий ActionLink будет указывать значение необязательного параметра из текущего контекста маршрута.

Это многословное объяснение, я думаю, что код поможет прояснить.

Контроллер

public virtual ActionResult Today(int? lineNumber = null)
{
    return Index(DateTime.Today, DateTime.Today, lineNumber);
}

Маршрут

context.MapRoute(
    "TodaysProductionSchedules",
    "Production/{Controller}/Today/{lineNumber}",
    new
        {
            area = AreaName,
            controller = MVC.Production.ProductionSchedules.Name,
            action = MVC.Production.ProductionSchedules.ActionNames.Today,
            lineNumber = UrlParameter.Optional
        });

Бритва

@Html.ActionLink("Show Today", MVC.Production.ProductionSchedules.Today(null))

Как я упоминал ранее, если я в данный момент не нахожусь в представлении, которое сопоставлено с этим маршрутом, ссылка будет сгенерирована правильно. Однако, если текущее представление отображает этот маршрут, И я либо опускаю значение, либо предоставляю null (как показано во фрагменте бритвы), параметр lineNumber примет свое значение из текущего значения маршрута.

Я думаю, что это может быть ошибка в T4MVC, поэтому я также размещу ссылку на эту тему на сайте codeplex T4MVC. Заранее спасибо!


person Vinney Kelly    schedule 19.07.2012    source источник
comment
Очевидным побочным шагом является сопоставление маршрута для версии URL без необязательного параметра, но я не рассматриваю этот ответ. Я скачал исходный код; возможно, у меня будет время, чтобы увидеть, не смогу ли я отладить эту ошибку самостоятельно :)   -  person Vinney Kelly    schedule 20.07.2012


Ответы (1)


Обновление от 30 июля 2012 г.: Исправлено в T4MVC 2.10.1!

На самом деле это был недавний регресс после изменения распаковщика модели. В t4mvc.tt вокруг строки 639 вы можете попробовать изменить AddRouteValues ​​​​на следующее:

    public static void AddRouteValues(RouteValueDictionary routeValueDictionary, string routeName, object routeValue) {
        IModelUnbinder unbinder;
        if (routeValue == null)
        {
            unbinder = DefaultModelUnbinder;
        }
        else
        {
            unbinder = ModelUnbinders.FindUnbinderFor(routeValue.GetType()) ?? DefaultModelUnbinder;
        }
        unbinder.UnbindModel(routeValueDictionary, routeName, routeValue);
    }

Исходный ответ: я думаю, что обычно в MVC во многих сценариях, когда значение отсутствует в новом маршруте, оно получает свое значение из текущего маршрута, предполагая, что значения высокого уровня одинаковы (отсюда и два разных случая вы видите).

Итак, теперь вопрос в том, может ли T4MVC сделать что-то, чтобы избежать такого поведения. Я не проверял точную логику, но, возможно, если бы он всегда устанавливал это значение в маршруте, это отключило бы это нежелательное поведение.

Но я думаю, что первым шагом является полное понимание поведения MVC, которое здесь играет роль, прежде чем заняться случаем T4MVC.

Не стесняйтесь продолжить расследование и отправить PR с исправлением! :)

person David Ebbo    schedule 22.07.2012
comment
Ты прав, Дэвид. Похоже, это непреднамеренное последствие поведения фреймворка по умолчанию. Забавно, я использую MVC с v3 (и T4MVC примерно столько же времени), и каким-то образом мне удалось избежать этой проблемы, но теперь я не могу ее избежать. Что меня действительно беспокоило, так это то, что, несмотря на то, что я указал null в качестве значения параметра, значение маршрута не изменилось. Не уверен (пока), связано ли это с T4MVC или самим MVC, но это определенно похоже на то, с чем T4 может (и, вероятно, должен) справиться. Вы согласны? - person Vinney Kelly; 24.07.2012
comment
Я согласен, что общее поведение не идеально. Обратите внимание, что в вашем примере передача null или вообще ничего не дает один и тот же IL, поэтому два случая не могут вести себя по-разному. Возвращаясь к прямому MVC, выяснили ли вы, что нужно передать в значениях маршрута, чтобы получить ожидаемое поведение? - person David Ebbo; 24.07.2012
comment
Да, @david, следующая ссылка создаст правильную ссылку: @Html.ActionLink("Today 2", "Today", new { lineNumber = (int?)null }) Это наводит меня на мысль, что проблему можно исправить с помощью немного другой обработки вспомогательных методов T4MVC без параметров. - person Vinney Kelly; 24.07.2012
comment
Ах да, я думаю, что я вижу проблему сейчас. Смотрите обновление в моем ответе. - person David Ebbo; 31.07.2012
comment
Исправление уже в T4MVC 2.10.1. - person David Ebbo; 31.07.2012
comment
Я заметил, что ваш комментарий, указывающий, что исправление находится в обновленной версии T4MVC, не загружается в исходный набор комментариев. Возможно, вы также захотите упомянуть об этом в принятом ответе. - person Vinney Kelly; 15.08.2012
comment
это меньшее, что я мог сделать; ваша отзывчивость и преданность T4MVC просто превосходны (как и инструмент, я могу добавить)! Эта библиотека — один из первых пакетов NuGet, которые я добавляю во все проекты MVC :) - person Vinney Kelly; 17.08.2012
comment
@DavidEbbo Что, если вам нужна эта функциональность, я хотел бы вывести значения маршрута из текущего контекста в моем T4MVC, но в моей текущей версии это не так (3.0.2), я собирался задать новый вопрос, но это первый попал в результаты Google, так что, вероятно, хорошо добавить его к ответу здесь. - person Paul Tyng; 04.12.2012
comment
@PaulTyng, может быть, что-то можно сделать. Хотите поэкспериментировать с возможными изменениями? - person David Ebbo; 05.12.2012
comment
@DavidEbbo Я подтверждаю, что эта проблема все еще существует в версии 3.17.4 :( - person Sadegh; 14.08.2016