wake-up-neo.com

aSP.NET MVC-Routing: Wie verwende ich Standardaktion, aber nicht-Standard-Parameter?

Ich schreibe die Frage um, da die bisherigen Antworten zeigen, dass ich sie nicht gut genug definiert habe. Ich werde die ursprüngliche Frage als Referenz unten belassen.

Beim Einrichten Ihres Routings können Sie Standardeinstellungen für verschiedene URL-/Routenteile festlegen. Betrachten wir ein Beispiel, das der VS-Assistent generiert:

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

Wenn in diesem Beispiel kein Controller angegeben ist, wird DefaultPageController verwendet. Wenn keine Aktion angegeben ist, wird die Aktion "Index" verwendet. Die URLs sehen im Allgemeinen wie folgt aus: http://mysite/MyController/MyAction.

Wenn die URL keine Aktion wie folgt enthält: http://mysite/MyController, wird die Indexaktion verwendet.

Nehmen wir nun an, ich habe zwei Aktionen in meinem Controller-Index und in AnotherAction. Die entsprechenden URLs sind http://mysite/MyController und http://mysite/MyController/AnotherAction. Meine "Index" -Aktion akzeptiert einen Parameter, id. Wenn ich also einen Parameter an meine Index-Aktion übergeben muss, kann ich Folgendes tun: http://mysite/MyController/Index/123. Beachten Sie, dass ich im Gegensatz zu URL http://mysite/MyController die Indexaktion explizit angeben muss. Ich möchte in der Lage sein, http://mysite/MyController/123 anstelle von http://mysite/MyController/Index/123 zu übergeben. Ich brauche keinen "Index" in dieser URL. Ich möchte, dass die MVC-Engine erkennt, dass, wenn ich nach http://mysite/MyController/123 frage, 123 keine Aktion ist (da ich keine Aktion mit diesem Namen definiert habe), sondern einen Parameter nach meinem Standard Aktion "Index". Wie richte ich das Routing ein, um dies zu erreichen?

Unten ist der ursprüngliche Wortlaut der Frage.


Ich habe einen Controller mit zwei Methoden wie folgt definiert

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

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

    }

Auf diese Weise kann ich URLs wie http://website/Page verarbeiten, sowohl wenn der Benutzer zu dieser URL navigiert (GET) als auch wenn er anschließend das Formular zurückschickt (POST).

Wenn ich nun den Beitrag zurückverarbeite, möchte ich in einigen Fällen den Browser auf diese URL umleiten:

http://website/Page/123

Wobei 123 eine ganze Zahl ist und ich eine Methode benötige, um diese URL in meinem Controller zu verarbeiten.

Wie richte ich das Routing ein, damit das funktioniert? Derzeit habe ich "Standard" -Routing vom Assistenten wie folgt generiert:

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

Ich habe versucht, eine andere Controller-Methode wie diese hinzuzufügen:

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

Dies funktioniert jedoch nicht, da eine mehrdeutige Aktionsausnahme ausgelöst wird:

Die aktuelle Anforderung der Aktion 'Index' für den Controllertyp 'PageController' ist zwischen den folgenden Aktionsmethoden nicht eindeutig: System.Web.Mvc.ActionResult Index () für den Typ PageController System.Web.Mvc.ActionResult Index (Int32) für den Typ PageController

Ich muss hinzufügen, dass ich auch andere Aktionen in diesem Controller habe. Das hätte funktioniert, wenn ich es nicht getan hätte.

17
Andrew Savinykh

So kann dies gelöst werden:

Sie können eine Routenbeschränkung erstellen, um der Routing-Engine mitzuteilen, dass, wenn Sie etwas in URL haben, das wie eine Zahl aussieht (123), dies ein Aktionsparameter für die Standardaktion ist und wenn Sie etwas haben, das nicht wie eine Nummer (AnotherAction) dann ist es eine Aktion.

Betrachten Sie diesen Code:

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

Diese Routendefinition stimmt nur mit numerischen Werten in http://mysite/MyController/123 hinter MyController überein, sodass das Aufrufen einer anderen Aktion auf demselben Controller nicht beeinträchtigt wird.

Quelle: Erstellen einer Routenbeschränkung

11
Andrew Savinykh

Wenn Sie den Variablennamen beibehalten, um die ID zu bleiben, müssen Sie nichts ändern.

Benennen Sie den Beitrag in "PostIndex" um und fügen Sie dieses Attribut hinzu:

[ActionName("Index")]

Dieselbe Frage zu SO hier .

Ok, hier ist eine Antwort zum Ausschneiden/Einfügen, falls das hilft.

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

Oh, ich habe es jetzt verstanden. Ich denke, es ist mit der Standardroute nicht möglich. Sie müssen benutzerdefinierte Routen zuordnen.

    // /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. Standardrouten wie/MyController/id müssen zuletzt zugeordnet werden.

1
cem

Ich denke, Sie möchten dieselbe Ansicht wiedergeben, aber Sie müssen verstehen, dass Sie zwei verschiedene Dinge tun. Eine ist Empfangspost, und eine andere greift auf get zu und eine andere greift auf get und Parameter zu.

Sie sollten 3 Aktionsergebnisse mit unterschiedlichen Namen ausführen und dieselbe Ansicht wie "Ansicht" ("ThisIsTheResult") zurückgeben.

0
Alberto León