it-swarm.com.de

Wie route ich eine URL mit einer Querzeichenfolge in ASP.NET MVC?

Ich versuche, eine benutzerdefinierte Route in MVC einzurichten, um eine URL von einem anderen System im folgenden Format zu übernehmen:

../ABC/ABC01?Key=123&Group=456

Die 01 nach dem zweiten ABC ist eine Schrittnummer, die sich ändert und die Key- und Group-Parameter ändern. Ich muss dies zu einer Aktion in einer Steuerung mit der Schrittnummerntaste und der Gruppe als Parameter leiten. Ich habe folgenden Code ausprobiert, es wird jedoch eine Ausnahme ausgelöst:

Code:

routes.MapRoute(
    "OpenCase", 
    "ABC/ABC{stepNo}?Key={key}&Group={group}",
    new {controller = "ABC1", action = "OpenCase"}
);

Ausnahme:

`The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character.`
32
Jason Underhill

Sie können die Abfragezeichenfolge nicht in die Route aufnehmen. Versuchen Sie es mit einer Route wie dieser:

routes.MapRoute("OpenCase", "ABC/ABC{stepNo}",
   new { controller = "ABC1", action = "OpenCase" });

Fügen Sie dann auf Ihrem Controller eine Methode wie folgt hinzu:

public class ABC1 : Controller
{
    public ActionResult OpenCase(string stepno, string key, string group)
    {
        // do stuff here
        return View();
    }        
}

ASP.NET MVC ordnet die Abfragezeichenfolgeparameter automatisch den Parametern in der Methode im Controller zu. 

39
Hector Correa

Bei der Definition von Routen können Sie keinen / am Anfang der Route verwenden:

routes.MapRoute("OpenCase",
    "/ABC/{controller}/{key}/{group}", <-- Bad; see / at beginning
    new { controller = "", action = "OpenCase" },
    new { key = @"\d+", group = @"\d+" }
    );

routes.MapRoute("OpenCase",
    "ABC/{controller}/{key}/{group}", <-- Good; No /  at beginning
    new { controller = "", action = "OpenCase" },
    new { key = @"\d+", group = @"\d+" }
    );

Versuche dies:

routes.MapRoute("OpenCase",
    "ABC/{controller}/{key}/{group}",
    new { controller = "", action = "OpenCase" },
    new { key = @"\d+", group = @"\d+" }
    );

Dann sollte Ihre Aktion wie folgt aussehen:

public ActionResult OpenCase(int key, int group)
{
    //do stuff here
}

Es sieht so aus, als würden Sie stepNo und "ABC" zusammenstellen, um einen Controller zu erhalten, der ABC1 ist. Deshalb habe ich diesen Abschnitt der URL durch {controller} ersetzt. 

Da Sie auch über eine Route verfügen, die "Schlüssel" und "Gruppe" definiert, wird die oben genannte Route auch Ihre ursprüngliche URL abfangen und an die Aktion senden.

4
George Stocker

Es gibt keinen Grund, in einem neuen ASP.NET MVC-Projekt das Routing zu verwenden, das auf Abfragen basiert. Dies kann für alte Projekte nützlich sein, die aus einem klassischen ASP.NET-Projekt konvertiert wurden und die URLs beibehalten werden sollen.

Eine Lösung kann das Attribut-Routing sein.

Eine andere Lösung kann darin bestehen, ein benutzerdefiniertes Routing zu schreiben, indem es von RouteBase abgeleitet wird:

public class MyOldClassicAspRouting : RouteBase
{

  public override RouteData GetRouteData(HttpContextBase httpContext)
  {
    if (httpContext.Request.Headers == null) //for unittest
      return null;

    var queryString = httpContext.Request.QueryString;

    //add your logic here based on querystring
    RouteData routeData = new RouteData(this, new MvcRouteHandler());
    routeData.Values.Add("controller", "...");
    routeData.Values.Add("action", "...");
  }

  public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
  {
     //Implement your formating Url formating here
     return null;
  }
}

Registrieren Sie Ihre benutzerdefinierte Routing-Klasse

public static void RegisterRoutes(RouteCollection routes)
{
  ...

  routes.Add(new MyOldClassicAspRouting ());
}
1
Tomas Kubes

Die Abfragezeichenfolgeargumente sind im Allgemeinen spezifisch für diesen Controller und für diese spezifische Anwendungslogik. 

Es ist also besser, wenn dies nicht in Routenregeln steht, die allgemein sind.

Sie können die Erkennung der Abfragezeichenfolge in das Aktionsargument auf folgende Weise einbetten.

Ich denke, dass es besser ist, einen Controller für StepNo zu haben.

public class ABC : Controller
{
    public ActionResult OpenCase(OpenCaseArguments arg)
    {
        // do stuff here
        // use arg.StepNo, arg.Key and arg.Group as You need
        return View();
    }        
}

public class OpenCaseArguments
{
    private string _id;
    public string id
    {
        get
        {
            return _id;
        }

        set
        {
            _id = value; // keep original value;
            ParseQueryString(value);
        }
    }

    public string  StepNo { get; set; }
    public string Key { get; set; }
    public string Group { get; set; }

    private void ParseQueryString(string qs)
    {
        var n = qs.IndexOf('?');
        if (n < 0) return;
        StepNo = qs.Substring(0, n); // extract the first part eg. {stepNo}
        NameValueCollection parms = HttpUtility.ParseQueryString(qs.Substring(n + 1));
        if (parms.Get("Key") != null) Key = parms.Get("Key");
        if (parms.Get("Group") != null) Group = parms.Get("Group");
    }

}

ModelBinder weist dem id-Feld von OpenCaseArguments den Wert {id} zu. Die set-Methode behandelt eine Split-Logik.

Und so weiter routen. Hinweis Routing ruft die Querzeichenfolge im ID-Argument ab.

routes.MapRoute(
    "OpenCase", 
    "ABC/OpenCase/{id}",
    new {controller = "ABC", action = "OpenCase"}
);

Ich habe diese Methode verwendet, um den Schlüsselwert mehrerer Felder für die Controller-Aktion zu erhalten.

0
RFex