web-dev-qa-db-fra.com

asp.net mvc routing: comment utiliser l'action par défaut mais un paramètre autre que celui par défaut?

Je suis en train de réécrire la question, car les réponses me montrent jusqu'à présent que je ne l'ai pas assez bien définie. Je laisserai la question initiale pour référence ci-dessous.

Lorsque vous configurez votre routage, vous pouvez spécifier des valeurs par défaut pour différentes parties d'URL/de routage. Prenons l'exemple que l'assistant VS génère:

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional } // Parameter defaults

Dans cet exemple, si le contrôleur n'est pas spécifié, DefaultPageController sera utilisé et si l'action n'est pas spécifiée, l'action "Index" sera utilisée. Les URL ressemblent généralement à: http://mysite/MyController/MyAction.

S'il n'y a pas d'action dans Url comme ceci: http://mysite/MyController, l'action d'index sera utilisée.

Supposons maintenant que j'ai deux actions dans mon contrôleur Index et dans une autre action. Les URL qui leur correspondent sont http://mysite/MyController et http://mysite/MyController/AnotherAction respectivement. Mon action "Index" accepte un paramètre, id. Donc, si je dois passer un paramètre à mon action Index, je peux le faire: http://mysite/MyController/Index/123. Notez que contrairement à l'URL http://mysite/MyController, je dois spécifier explicitement l'action Index. Ce que je veux faire, c'est pouvoir passer http://mysite/MyController/123 au lieu de http://mysite/MyController/Index/123. Je n'ai pas besoin de "Index" dans cette URL, je veux que le moteur MVC reconnaisse que lorsque je demande http://mysite/MyController/123, 123 n'est pas une action (car je n'ai pas défini d'action avec ce nom), mais un paramètre à ma valeur par défaut action "Index". Comment puis-je configurer le routage pour y parvenir?

Vous trouverez ci-dessous le libellé original de la question.


J'ai un contrôleur avec deux méthodes définies comme ça

    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(SomeFormData data)
    {
        return View();

    }

Cela me permet de traiter une URL telle que http://website/Page lorsque l'utilisateur accède à cette URL (GET) et lorsqu'il poste ensuite le formulaire (POST).

Maintenant, lorsque je traite la publication, dans certains cas, je veux rediriger le navigateur vers cette URL:

http://website/Page/123

Où 123 est un nombre entier et j'ai besoin d'une méthode pour traiter cette URL dans mon contrôleur.

Comment configurer le routage pour que cela fonctionne? Actuellement, j'ai un routage "par défaut" généré par l'assistant comme ceci:

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional } // Parameter defaults

J'ai essayé d'ajouter une autre méthode de contrôleur comme celle-ci:

public ActionResult Index(int id)
{
    return View();
}

Mais cela ne fonctionne pas car une exception d'action ambiguë est levée:

La demande d'action "Index" actuelle sur le type de contrôleur "PageController" est ambiguë entre les méthodes d'action suivantes: System.Web.Mvc.ActionResult Index () sur le type PageController System.Web.Mvc.ActionResult Index (Int32) sur le type PageController

Je dois ajouter que j'ai également d'autres actions dans ce contrôleur. Cela aurait fonctionné si je ne l'avais pas fait.

17
Andrew Savinykh

Voici comment cela peut être résolu:

Vous pouvez créer une contrainte de route, pour indiquer au moteur de routage, que si vous avez quelque chose dans l'URL qui ressemble à un nombre (123), il s'agit d'un paramètre d'action pour l'action par défaut et si vous avez quelque chose qui ne ressemble pas à un nombre (AnotherAction) alors c'est une action.

Considérez ce code:

routes.MapRoute(
  "MyController", "MyController/{productId}", 
  new {controller="My", action="Index"}, 
  new {productId = @"\d+" });

Cette définition de route ne fera correspondre que les valeurs numériques après MyController dans http://mysite/MyController/123, de sorte qu'elle n'interférera pas avec l'appel d'une autre action sur le même contrôleur.

Source: Création d'une contrainte de route

11
Andrew Savinykh

Si vous conservez le nom de la variable comme identifiant, vous n'avez rien besoin de changer.

Renommez le post one en "PostIndex" et ajoutez cet attribut:

[ActionName("Index")]

Même question sur SO ici .

Ok, voici une réponse couper/coller pour vous, si cela peut vous aider.

public ActionResult Index()    {        
return View();    
}    
[AcceptVerbs(HttpVerbs.Post), ActionName("Index")]   
public ActionResult PostIndex(SomeFormData data)    {        
return View();    
}
3
NKCSS

Oh je l'ai maintenant. Je pense que ce n'est pas possible avec la route par défaut, vous devez mapper des routes personnalisées.

    // /MyController/AnotherAction
    routes.MapRoute(
        null,
        "MyController/AnotherAction",
        new { controller = "DefaultPage", action = "AnotherAction" }
    );

    // /MyController
    // /MyController/id
    routes.MapRoute(
        null,
        "MyController/{id}",
        new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional }
    );

ps. Itinéraires par défaut comme/MyController/id doivent enfin être mappés.

1
cem

Je pense que vous voulez retrouver le même point de vue, mais vous devez comprendre que vous faites deux choses différentes. Un est recevoir un message, et un autre est d'accéder par get, et un autre est d'accéder par get et paramètre ...

Vous devez faire 3 résultats d’action avec des noms différents et retourner la même vue que View ("ThisIsTheResult")

0
Alberto León