DefaultInlineConstraintResolver-Fehler in WebAPI 2

140

Ich verwende Web-API 2 und erhalte die folgende Fehlermeldung, wenn ich einen POST mit IIS 7.5 auf meiner lokalen Box an meine API-Methode sende.

The inline constraint resolver of type 'DefaultInlineConstraintResolver' was unable to resolve the following inline constraint: 'string'.

Line 21: GlobalConfiguration.Configuration.EnsureInitialized();

Keine meiner APIs funktioniert mit IIS. Ich kann mein API-Projekt jedoch in Visual Studio mit IIS Express ausführen und erfolgreich einen POST für meine Anmelde-API durchführen. Wenn ich jedoch versuche, eine GET-Anforderung an einen anderen API-Aufruf zu senden, wird der Fehler beim Auflösen von Einschränkungen angezeigt.

Um dies zu beheben, habe ich in Visual Studio ein brandneues Web-API-2-Projekt erstellt und die vorhandenen APIs einzeln in das neue Projekt importiert und ausgeführt, um sicherzustellen, dass sie funktionieren. Wenn ich IIS Express mit diesem neuen Projekt verwende, erhalte ich genau die gleichen Ergebnisse wie mit meinem vorhandenen API-Projekt.

Was fehlt mir hier? Selbst mit einem brandneuen Projekt bin ich nicht in der Lage, GET-Anfragen zu stellen, ohne auf dieses Problem mit dem Constraint Resolver zu stoßen.

Halcyon
quelle

Antworten:

279

Der Fehler bedeutet, dass Sie irgendwo in einer Route so etwas wie angegeben haben

[Route("SomeRoute/{someparameter:string}")]

"string" wird nicht benötigt, da es sich um den angenommenen Typ handelt, wenn nichts anderes angegeben ist.

Wie der Fehler anzeigt, wird für die DefaultInlineConstraintResolvermitgelieferte Web-API keine Inline-Einschränkung aufgerufen string. Die standardmäßig unterstützten sind die folgenden:

// Type-specific constraints
{ "bool", typeof(BoolRouteConstraint) },
{ "datetime", typeof(DateTimeRouteConstraint) },
{ "decimal", typeof(DecimalRouteConstraint) },
{ "double", typeof(DoubleRouteConstraint) },
{ "float", typeof(FloatRouteConstraint) },
{ "guid", typeof(GuidRouteConstraint) },
{ "int", typeof(IntRouteConstraint) },
{ "long", typeof(LongRouteConstraint) },

// Length constraints
{ "minlength", typeof(MinLengthRouteConstraint) },
{ "maxlength", typeof(MaxLengthRouteConstraint) },
{ "length", typeof(LengthRouteConstraint) },

// Min/Max value constraints
{ "min", typeof(MinRouteConstraint) },
{ "max", typeof(MaxRouteConstraint) },
{ "range", typeof(RangeRouteConstraint) },

// Regex-based constraints
{ "alpha", typeof(AlphaRouteConstraint) },
{ "regex", typeof(RegexRouteConstraint) }
Kiran Challa
quelle
2
Das macht Sinn, warum ich die Fehler gesehen habe. Ich hatte {string: type} in meinem Routenattribut. Ich habe es entfernt und es funktioniert jetzt.
Halcyon
3
@AndreasFurster: Da stringkeine Einschränkung angewendet werden kann.
Dave New
31
"string" wird nicht benötigt, da es sich um den angenommenen Typ handelt, wenn nichts anderes angegeben ist.
Andrew Jens
1
@ AndrewGray Diese Liste ist hier verfügbar: asp.net/web-api/overview/web-api-routing-and-actions/…
Elijah Lofgren
2
Falls das Problem darin bestand, dass das Routenattribut wie folgt lautet: {string: type}, entfernen Sie einfach den 'string:'
Asaf
33

Eine weitere Sache, wenn Sie int, bool oder eine andere Einschränkung nicht verwenden können, ist dies von entscheidender Bedeutung und Sie müssen alle Leerzeichen entfernen.

//this will work
[Route("goodExample/{number:int}")]
[Route("goodExampleBool/{isQuestion:bool}")]
//this won't work
[Route("badExample/{number : int}")]
[Route("badExampleBool/{isQuestion : bool}")]
Serban Popescu
quelle
1
Sie würden denken, dass sie trim()diese nach dem Teilen und vor dem Vergleichen haben ... Das Nicht-Trimmen von Saiten, die als Schlüssel verwendet werden, ist ein großer Ärger von mir, der bis in meine FoxPro-Tage zurückreicht.
DVK
10

Ich habe diesen Fehler auch erhalten, als ich ein Leerzeichen zwischen dem Variablennamen und dem Variablentyp in der Route gelassen habe, wie folgt:

[HttpGet]
[Route("{id: int}", Name = "GetStuff")]

Es sollte folgendes sein:

[HttpGet]
[Route("{id:int}", Name = "GetStuff")]
Lateinischer Krieger
quelle
1

Ich habe eine API-Route für eine Undo-Web-API-Methode entworfen und versucht, die Überprüfung des ENUM-Datentyps auf die Aktion in der Route anzuwenden. Dabei ist der Fehler DefaultInlineConstrainResolver aufgetreten

Fehler: System.InvalidOperationException: 'Der Inline-Einschränkungsauflöser vom Typ' DefaultInlineConstraintResolver 'konnte die folgende Inline-Einschränkung nicht auflösen:' ActionEnum '

[HttpGet]
[Route("api/orders/undo/{orderID}/action/{actiontype: OrderCorrectionActionEnum}")]
public IHttpActionResult Undo(int orderID, OrderCorrectionActionEnum actiontype)
{
    _route(undo(orderID, action);
}

public enum OrderCorrectionActionEnum
{
    [EnumMember]
    Cleared,

    [EnumMember]
    Deleted,
}

Um die ENUM-Einschränkung anzuwenden, müssen Sie OrderCorrectionEnumRouteConstraintmithilfe von benutzerdefinierte Elemente erstellen IHttpRouteConstraint.

public class OrderCorrectionEnumRouteConstraint : IHttpRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        // You can also try Enum.IsDefined, but docs say nothing as to
        // is it case sensitive or not.
        var response = Enum.GetNames(typeof(OrderCorrectionActionEnum)).Any(s = > s.ToLowerInvariant() == values[parameterName].ToString().ToLowerInvariant());
        return response;
    }

    public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary< string, object> values, HttpRouteDirection routeDirection)
    {
        bool response = Enum.GetNames(typeof(BlockCorrectionActionEnum)).Any(s = > s.ToLowerInvariant() == values[parameterName].ToString().ToLowerInvariant());
        return response;              
    }
}

Referenz (Dies ist mein Blog): https://rajeevdotnet.blogspot.com/2018/08/web-api-systeminvalidoperationexception.html für weitere Details

Rajeev Tiwari
quelle
0

Ich habe diesen Fehler erhalten, wenn Type als Zeichenfolge deklariert wurde. Als ich das in int änderte, fing es an zu funktionieren

[HttpGet][Route("testClass/master/{Type:string}")]
VinayKumarHA
quelle