web-dev-qa-db-fra.com

Affectation de plusieurs routes au même contrôleur ou action dans ASP MVC 6

Question:

Existe-t-il un moyen d'affecter deux routes différentes (avec des paramètres) au même contrôleur dans une application ASP.NET MVC 6?

J'ai essayé:

J'ai essayé d'utiliser plusieurs attributs de route pour la classe de contrôleur et également pour les actions individuelles, cela n'a pas fonctionné.

Notes:

  • J'utilise ASP.NET Core 1.0 RC1.

  • La raison pour laquelle je veux le faire est que je veux que l'API soit compatible avec l'ancienne version de notre application mobile qui utilise l'ancienne URL.

Exemple:

[Produces("application/json")]
[Route("api/v2/Log")]
/// The old route is "api/LogFile" which I want to be still valid for this controller.
public class LogController : Controller {
    [HttpGet("{id}", Name = "download")]
    public IActionResult GetFile([FromRoute] Guid id) 
    {
        // ...
    }
}

Dans l'exemple ci-dessus: api/LogFile/{some-guid} est l'ancienne route et api/v2/log/download/{some-guid} est la nouvelle route. J'ai besoin que les deux routes invoquent la même action.

31
A-Sharabiani

Avoir 2 attributs de route au niveau du contrôleur fonctionne très bien dans une nouvelle application RC1:

[Produces("application/json")]
[Route("api/[controller]")]
[Route("api/old-log")]
public class LogController: Controller
{
    [HttpGet]
    public IActionResult GetAll()
    {
        return Json(new { Foo = "bar" });
    }
}

Tous les deux http://localhost:62058/api/log et http://localhost:62058/api/old-log retourne le json attendu. La seule mise en garde que j'ai vue est que vous souhaiterez peut-être définir les propriétés de nom/ordre des attributs au cas où vous auriez besoin de générer l'URL pour l'une de ces actions.

Avoir 2 attributs sur l'action fonctionne également:

[Produces("application/json")]        
public class LogController : Controller
{
    [Route("api/old-log")]
    [Route("api/[controller]")]
    [HttpGet]
    public IActionResult GetAll()
    {
        return Json(new { Foo = "bar" });
    }
}

Cependant, vous devez être prudent lorsque vous avez un itinéraire général au niveau du contrôleur et un itinéraire d'action spécifique. Dans ces cas, la route au niveau du contrôleur est utilisée comme préfixe et ajoutée à l'url (il y a un bel article sur ce comportement ici ). Cela pourrait vous donner un ensemble d'URL différent de celui auquel vous vous attendiez, par exemple avec:

[Produces("application/json")]
[Route("api/[controller]")]
public class LogController : Controller
{
    [Route("api/old-log")]
    [Route("")]
    [HttpGet]
    public IActionResult GetAll()
    {
        return Json(new { Foo = "bar" });
    }
}

Les 2 itinéraires que votre application écoutera dans le dernier cas seront http://localhost:62058/api/log et http://localhost:62058/api/log/api/old-log puisque api/log est ajouté comme préfixe à toutes les routes définies au niveau de l'action.

Enfin, une autre option serait d'utiliser des attributs pour vos nouveaux itinéraires, puis d'utiliser la table de routage dans la classe de démarrage pour fournir des itinéraires spécifiques qui prennent en charge l'ancienne API.

52
Daniel J.G.