Почему ASP.NET-MVC Routing UrlParameter.Optional игнорируется при использовании этого регулярного выражения? - PullRequest
4 голосов
/ 10 февраля 2011

Это упрощенный пример проблемы, с которой я столкнулся сегодня утром, с маршрутизацией URL ASP.NET MVC.

Довольно просто, я хотел, чтобы вызывалось действие маршрута независимо от того, был ли параметр вend был предоставлен.

Этот маршрут работает нормально, соответствуя / apple / и / apple / test /

routes.MapRoute(
    "Working Route",
    "apple/{parameter}",
    new { 
        controller = "Apple", 
        action = "Action", 
        parameter = UrlParameter.Optional
    },
    new { parameter = @"([a-z0-9\.-]+)" }
);

Однако этотвторой маршрут будет соответствовать только / банан / тест / и тому подобное.Когда я пытаюсь / banana / , маршрутизатор просто проходит прямо через него и возвращает ошибку универсального сообщения 404.

routes.MapRoute(
    "Non-Working Route",
    "banana/{parameter}",
    new { 
        controller = "Banana", 
        action = "Action", 
        parameter = UrlParameter.Optional
    },
    new { parameter = @"([a-z0-9]+)" }
);

Единственное отличие заключается в проверке параметров в Regex, нопоскольку это довольно простое совпадение с Regex, они оба должны отлично работать для URL, например / banana / , но второй маршрут просто не может его распознать.

Я обошел проблемупросто изменив Regex на маршруте # 2, чтобы он соответствовал этому на маршруте # 1, и примите '.'и символы «-», я просто подумал, знает ли кто-нибудь, почему это происходит.

РЕДАКТИРОВАТЬ:

Вот контроллеры и действия, которые я использую для моего примера.Здесь ничего необычного.

public class AppleController : Controller
{
    public ActionResult Action(string parameter)
    {
        if (parameter == null)
        {
            parameter = "No parameter specified.";
        }
        ViewData["parameter"] = parameter;
        return View();
    }
}

public class BananaController : Controller
{
    public ActionResult Action(string parameter)
    {
        if (parameter == null)
        {
            parameter = "No parameter specified.";
        }
        ViewData["parameter"] = parameter;
        return View();
    }
}

Так что моя проблема в том, что / apple / будет отображать «Параметр не указан», тогда как / banana / дает мне нежелательныеВместо 404.

Пока ..

Использование параметр = URLParameter.Optional в объявлении маршрута: маршрут № 1 работает отлично, маршрут № 2 не соответствует без параметра.

Использование параметр = "" в объявлении маршрута: оба маршрута № 1 и маршрут № 2 не совпадают, если параметр не указан в URL.

Объявление параметр = "" в сигнатуре метода Action: невозможно из-за версии .NET.

Удаление всех других маршрутов не имеет никакого эффекта.

Ответы [ 2 ]

4 голосов
/ 10 февраля 2011

Если токен является необязательным, то используемое вами ограничение регулярного выражения также должно отражать это, например, (foo)?.

Мне удалось воспроизвести эту проблему с ASP.NET MVC 2 на .NET 4.Затем я обновился до ASP.NET MVC 3, и все заработало как положено.Представленное выше решение не работает с ASP.NET MVC 2, но работает с ASP.NET MVC 3, поэтому я могу только предположить, что это ошибка в v2, которая теперь исправлена ​​в v3.может ссылаться на v2 и использовать это в web.config для тестирования с v3:

<runtime>
   <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
         <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
         <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
   </assemblyBinding>
</runtime>
0 голосов
/ 10 февраля 2011

2-е РЕДАКТИРОВАНИЕ

Соответствующие ~ / фрукты / и ~ фрукты / яблоко

routes.MapRoute(
    "Working Route",
    "Fruit/{fruit}",
    new
    {
        controller = "Fruit",
        action = "Index",
        fruit = ""
    },
    new { fruit = @"([a-z0-9\.-]+)" }
);

public ActionResult Index(string fruit)
{
    ViewData["fruit"] = !String.IsNullOrEmpty(fruit) ? fruit : "None specified.";
    return View();
}

Соответствует ~ / банан / и ~ / банан / желтый

routes.MapRoute(
    "Non-Working Route",
    "Banana/{color}",
    new
    {
        controller = "Banana",
        action = "Index",
        color = ""
    },
    new { color = @"([a-z0-9]+)" }
);

public ActionResult Index(string color)
    {
        ViewData["Color"] = color;
        return View();
    }

1-е РЕДАКТИРОВАНИЕ

Попробуйте на самом деле установить параметр как необязательный для сигнатуры действия, например: string parameter = ""


Я не понимаю этого поведения. Оба маршрута работают для меня, как вы их описываете (второй маршрут выдает 404, если я добавлю «-» к маршруту, но это ожидается). Как выглядит ваша подпись метода действия?

Я установил свой маршрут (и контроллер / вид) так:

routes.MapRoute(
    "Working Route",
    "Fruit/{fruit}",
    new
    {
        controller = "Fruit",
        action = "Index",
        fruit = UrlParameter.Optional
    },
    new { fruit = @"([a-z0-9]+)" }
);

И мое действие Index () выглядит так:

public ActionResult Index(string fruit = "")
{
    ViewData["fruit"] = fruit;
    return View();
}
...