/ / Roteamento MVC - conflito entre o parâmetro e o nome do controlador - asp.net-mvc, asp.net-mvc-4

Roteamento MVC - conflito entre o parâmetro e o nome do controlador - asp.net-mvc, asp.net-mvc-4

Como posso resolver as seguintes regras de roteamento sem conectá-las explicitamente?

Eu gostaria de adicionar URLs amigáveis ​​por motivos de promoção, como:

domain.com/promoA
domain.com/promoB

Isso deve ser tratado por um único controlador de "promoções". (Não me importo se isso for tratado pelo controlador "doméstico")

Então, eu gostaria de ter URLs do seguinte formulário mapeados diretamente para um controlador

domain.com/account       ---> controller=account, action=index
domain.com/account/login ---> controller=account, action=login
domain.com/product/list  ---> controller=product, action=list
domain.com               ---> controller=home, action=index

É possível?

Obrigado!

Respostas:

1 para resposta № 1

Não tenho certeza se essa é a maneira mais fácil, mas você pode definir uma rota com uma restrição. Apenas certifique-se de declará-lo antes de suas outras rotas.

routes.MapRoute(
"Promos", // Route name
"{action}", // URL with parameters
new { controller = "Promotions", }, // Parameter defaults
new { action = new PromoConstraint(), }
);

Onde PromoConstraint é definido como

public class PromoConstraint : IRouteConstraint
{
private readonly List<string> _promos = new List<string> { "promoA", "promoB", };

public bool Match(
HttpContextBase httpContext
, Route route
, string parameterName
, RouteValueDictionary values
, RouteDirection routeDirection
)   {
object value;
if(!values.TryGetValue(parameterName, out value)) return false;

var str = value as string;
if(str == null) return false;

return _promos.Any(promo => promo.ToLower() == str.ToLower());
}
}

0 para resposta № 2

Sim, é possível.

Tudo que você precisa fazer é ter a ação Índiceno controlador inicial, verifique se o produto fornecido existe na tabela de produtos. Em caso afirmativo, retorne a visualização desse produto, caso contrário, apenas retorne a visualização do índice.

Você precisaria configurar rotas para todos os outros controladores, como descreveu em sua pergunta.

E sua rota raiz precisaria especificar que levará um parâmetro opcional "produto".

routes.MapRoute("Root",   "{product}",   new { controller = "Home", action = "Index", product = "" });

Se eles seguirem um determinado padrão, você pode adicionar uma nova rota que manipularia essas promos adicionando uma restrição usando uma expressão regular.