Błąd DefaultInlineConstraintResolver w WebAPI 2

140

Używam interfejsu API sieci Web 2 i otrzymuję następujący błąd podczas wysyłania POST do mojej metody interfejsu API przy użyciu usług IIS 7.5 na moim lokalnym polu.

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

Line 21: GlobalConfiguration.Configuration.EnsureInitialized();

Żaden z moich interfejsów API nie działa przy użyciu usług IIS. Mogę jednak uruchomić projekt interfejsu API w programie Visual Studio przy użyciu usług IIS Express i pomyślnie wykonać POST do mojego interfejsu API logowania, ale gdy próbuję wykonać żądanie GET do innego wywołania interfejsu API, pojawia się błąd mechanizmu rozpoznawania ograniczeń.

Aby rozwiązać ten problem, utworzyłem nowy projekt Web API 2 w programie Visual Studio i zacząłem importować istniejące interfejsy API do nowego projektu pojedynczo i uruchamiać je, aby upewnić się, że działają. Używając IIS Express w nowym projekcie, otrzymuję dokładnie takie same wyniki, jak w przypadku mojego istniejącego projektu API.

Czego tu brakuje? Nawet przy zupełnie nowym projekcie nie mogę wysyłać żądań GET bez napotkania tego problemu z rozpoznawaniem ograniczeń.

Zimorodek
źródło

Odpowiedzi:

279

Błąd oznacza, że ​​gdzieś w Route, podałeś coś takiego jak

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

„string” nie jest potrzebny, ponieważ jest to typ przyjęty, jeśli nie określono nic innego.

Jak wskazuje błąd, ten DefaultInlineConstraintResolverinterfejs API sieci Web jest dostarczany z nie ma wbudowanego ograniczenia o nazwie string. Domyślnie obsługiwane są następujące:

// 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
źródło
2
To ma sens, dlaczego widziałem błędy. W atrybucie trasy miałem {string: type}. Usunąłem go i teraz działa.
Halcyon
3
@AndreasFurster: Ponieważ stringnie można zastosować żadnego ograniczenia.
Dave New
31
„string” nie jest potrzebny, ponieważ jest to typ przyjęty, jeśli nie określono nic innego.
Andrew Jens
1
@AndrewGray Ta lista jest dostępna tutaj: asp.net/web-api/overview/web-api-routing-and-actions/…
Elijah Lofgren
2
W przypadku, gdy problem wynikał z atrybutu trasy, takiego jak: {string: type}, po prostu usuń ciąg „string:”
Asaf
33

I jeszcze jedna rzecz, jeśli nie możesz użyć int, bool lub innego ograniczenia, jest on wrażliwy na klucz i musisz usunąć wszelkie spacje.

//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
źródło
1
Można by pomyśleć, że zrobili to trim()po rozdzieleniu i przed porównaniem ... Nie przycinanie strun używanych jako klucze jest moim głównym drażniącym zwierzakiem, cofając się aż do moich dni w FoxPro.
DVK,
10

Otrzymałem również ten błąd, gdy zostawiłem spację między nazwą zmiennej a typem zmiennej w trasie, na przykład:

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

Powinien wyglądać następująco:

[HttpGet]
[Route("{id:int}", Name = "GetStuff")]
Łaciński wojownik
źródło
1

Zaprojektowałem trasę API dla jednej metody Undo Web API i próbowałem zastosować walidację typu danych ENUM dla akcji w trasie i napotkałem poniżej Błąd DefaultInlineConstrainResolver

Błąd: System.InvalidOperationException: „Wbudowany mechanizm rozpoznawania ograniczeń typu„ DefaultInlineConstraintResolver ”nie może rozwiązać następującego ograniczenia wbudowanego:„ 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,
}

Aby zastosować ograniczenie ENUM, musisz utworzyć własne OrderCorrectionEnumRouteConstraintza pomocą 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;              
    }
}

Źródła informacji (to jest mój blog): https://rajeevdotnet.blogspot.com/2018/08/web-api-systeminvalidoperationexception.html, aby uzyskać więcej informacji

Rajeev Tiwari
źródło
0

Otrzymałem ten błąd, gdy wpisz jako zadeklarowany jako ciąg. Kiedy zmieniłem to na int, zaczęło działać

[HttpGet][Route("testClass/master/{Type:string}")]
VinayKumarHA
źródło