asp.net mvc - маршрут для строки или целого (т.е. / type / 23 или / type / hats) - PullRequest
5 голосов
/ 30 июня 2009

У меня есть следующий случай, когда я хочу принять следующие маршруты

 '/type/view/23' or '/type/view/hats'

, где 23 - идентификатор шляпы.

Контроллер выглядит примерно так:

public class TypeController
{ 
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult View(int id)
    {
      ...
    }
}

Теперь, если они пройдут через 23, никаких проблем. Если они проходят в шляпах, у меня есть работа. Теперь мне было интересно, смогу ли я в этом случае преобразовать шляпы в 23, используя ActionFilter, который проверяет, является ли значение, переданное в качестве идентификатора, целым числом (если это так, проверьте, что оно существует в базе данных), или если оно выглядит как строка до базы данных для того, что идентификатор строки, которая была передана в. В любом случае, если совпадение не найдено, я бы хотел перенаправить пользователя на другое действие.

Во-первых, правильный подход, который я назвал, во-вторых, возможно ли сделать перенаправление из ActionFilter.

Приветствие Энтони

Ответы [ 2 ]

4 голосов
/ 30 июня 2009

Измените свою подпись, чтобы принять строку. Затем проверьте, является ли значение id целочисленным. Если это так, то поиск по идентификатору, если не поиск по имени. Если вы не нашли соответствия, сделайте ваше перенаправление.

public class TypeController
{ 
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult View(string id)
    {
       Product product = null;
       int productID = -1;
       if (int.TryParse( id, out productID))
       {
           product = db.Products
                       .Where( p => p.ID == productID )
                       .SingleOrDefault();
       }
       else
       {
           product = db.Products
                       .Where( p => p.Name == id )
                       .SingleOrDefault();
       }

       if (product == null)
       {
           return RedirectToAction( "Error" );
       }
       ...
    }
}

Причина, по которой я бы сделал это, заключается в том, что для того, чтобы узнать, какой контроллер / действия применить, среда будет искать тот, который соответствует сигнатуре данных маршрута, которые были переданы. Если у вас нет Соответствующая подпись - в данном случае та, которая принимает строку - вы получите исключение до того, как любой из ваших фильтров будет вызван. К сожалению, я не думаю, что у вас может быть один, который принимает строку, а другой - int - в этом случае фреймворк не сможет сказать, какой из них должен соответствовать, если передан один параметр, по крайней мере, если он число, то есть. Делая это строковым параметром и обрабатывая перевод самостоятельно, вы позволяете фреймворку выполнять свою работу и получаете желаемое поведение - фильтр не нужен.

0 голосов
/ 30 июня 2009

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

Что касается перенаправления использования

return RedirectToAction("MyProfile", "Profile");

Вы можете передавать значения маршрута как часть вызова RedirectToAction, чтобы вы могли передавать идентификаторы или имена и т. Д., Если это то, что требуется.

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

...