Wie kann ich zwei verschiedene Abfrage-String params übergeben, die eine Aktion Methode param darstellen?

StackOverflow https://stackoverflow.com/questions/2315046

  •  22-09-2019
  •  | 
  •  

Frage

Ich habe eine Aktion Methode, wie die folgenden

got
public JsonResult Index(string version)
{
   .. do stuff, return some data v1 or v2. Default = v2.
}

Also, diese Aktion Methode gibt einige Daten, die entweder als Version 1 oder Version 2 formatiert werden können (was auch immer ausgegeben, das ist ... nur wissen, dass sie schemantically verschieden sind).

Also, wenn ein Benutzer Zugriff auf Anruf diese Ressource, sie wie folgt vor:

http://www.blah.com/api/Index

nichts zu hart.

Sie können auch dieses tun ...

http://www.blah.com/api/Index?version=1.0

Aber es ist möglich, es so zu machen, dass der Benutzer den Query-String-params version verwenden oder v

eg. http://www.blah.com/api/Index?v=1.0 

und dies wird die Versionsparameter im ActionMethod bevölkert. Möglich?

War es hilfreich?

Lösung

Ich vermute, Sie könnten die Aktionsmethode Parameter (n) unter Verwendung eines Action-Filter bearbeiten.

überprüfen Im Grunde nur für einen ‚v‘ in der QueryString Sammlung, und wenn es vorhanden ist, werfen sie in die ActionParameters Sammlung.

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var version = filterContext.HttpContext.Request.QueryString["v"];
    if (!string.IsNullOrEmpty(version))
        filterContext.ActionParameters["version"] = version;
}

HTHS,
Charles

EDIT: So dass es ein bisschen mehr Generika ...

public class QueryStringToActionParamAttribute : ActionFilterAttribute
{
    private string _queryStringName;
    private string _actionParamName;

    public QueryStringToActionParamAttribute(string queryStringName, string actionParamName)
    {
        _queryStringName = queryStringName;
        _actionParamName = actionParamName;
    }

    public override void OnActionExecuting(ActionExecutedContext filterContext)
    {
        var queryStringValue = filterContext.HttpContext.Request.QueryString[_queryStringName];
        if (!string.IsNullOrEmpty(queryStringValue))
        {
            filterContext.ActionParameters[_actionParamName] = queryStringValue;
        }
    }
}

Dann rufen Sie könnten es wie:

[QueryStringToActionParam("v", "version")];

Andere Tipps

Eine alternative Möglichkeit, die Versionierung der API zu handhaben ist tatsächlich verschiedene Versionen der Controller für jede API-Version muß, auf diese Weise brauchen Sie nicht alle die Prüfung für jede Versionsnummer in jeder Aktion-Methode haben. Jeder Controller ist eine Version der API nur anwendbar.

Die Reiniger (IMO) für mich übernehmen die Versionierung auf der Strecke Zeit statt Einwirkzeit. Sie können mit einer Routing-Einschränkung tun dies für die Versionsnummer zu überprüfen.

Im folgenden Beispiel der Controller V10 und V20 kann nur geführt werden, wenn die Route contraint vergangen - das heißt der Header vorhanden war, wenn keine Header der Standard (die v2 ist).

routes.MapRoute(
            "EmployeeListingv1",
            "employees",
            new { controller = "V10Employees", action = "Index" },  // Parameter defaults
            new { ApiV = new ApiVersionConstraint(ApiVersion.Version10) }
    );

routes.MapRoute(
                "EmployeeListingv2",
                "employees",
                new { controller = "V20Employees", action = "Index" },  // Parameter defaults
                new { ApiV = new ApiVersionConstraint(ApiVersion.Version20) }
        );

Sie könnten es tun, um den Query-String mit der Version passieren wie Sie gerade tun und nur auf eine Strecke Einschränkung ändern, jedoch habe ich finde es einfacher, mit einem optionalen Header in der Anfrage zu halten. (Es ist auch mehr „RESTful‘, ohne in diese ganze Debatte zu bekommen). Kein Kopfmittel Standard (letzte) Version der API.

Beispiel API Version Einschränkung:

/// <summary>
/// Enable routing of requests to controllers based on the 
/// API version contained in the header.
/// </summary>
public class ApiVersionConstraint : IRouteConstraint   
{
    const string VersionHeader = "X-MY-API-NAME-HERE-VERSION";

    private ApiVersion _version = ApiVersion.Unsupported;

    public ApiVersionConstraint(ApiVersion version)
    {
        this._version = version;
    }

    #region IRouteConstraint Members

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        string vers = string.Empty;

        if (httpContext.Request.Headers[VersionHeader] != null)
        {
            vers = httpContext.Request.Headers[VersionHeader];
        }
        else
        {
            vers = "2.0"; // set default here.
        }

        ApiVersion fromHeader = ApiVersion.Unsupported;

        switch (vers)
        {
            case "1.0":
                {
                    fromHeader = ApiVersion.Version10;
                    break;
                }
            case "2.0":
                {
                    fromHeader = ApiVersion.Version20;
                    break;
                }

            default:
                {
                    fromHeader = ApiVersion.Unsupported;
                    break;
                }
        }

        return fromHeader == _version;

    }

    #endregion
}

Nur etwas mehr auf diese alte Frage hinzufügen ... Sie können die Techniken kombinieren hier und so Unterstützung Version Auswahl von Request-Header oder Abfrage-String durch die Kontroll Wechsel in @ Rosstified Antwort eine Abfrage-Zeichenfolge-Check enthalten:

        if (httpContext.Request.Headers[VersionHeader] != null) {
            vers = httpContext.Request.Headers[VersionHeader];
        } else {
            if (httpContext.Request.QueryString["v"] != null) {
                vers = httpContext.Request.QueryString["v"];
            } else {
                vers = "1.0"; // set default here.
            }
        }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top