Konwertuję z interfejsu API sieci Web programu WCF do nowego interfejsu API sieci Web ASP.NET MVC 4. Mam UsersController i chcę mieć metodę o nazwie Authenticate. Widzę przykłady wykonywania GetAll, GetOne, Post i Delete, ale co zrobić, jeśli chcę dodać dodatkowe metody do tych usług? Na przykład moja usługa UsersService powinna mieć metodę o nazwie Authenticate, w której przekazuje nazwę użytkownika i hasło, jednak to nie działa.
public class UsersController : BaseApiController
{
public string GetAll()
{
return "getall!";
}
public string Get(int id)
{
return "get 1! " + id;
}
public User GetAuthenticate(string userName, string password, string applicationName)
{
LogWriter.Write(String.Format("Received authenticate request for username {0} and password {1} and application {2}",
userName, password, applicationName));
//check if valid leapfrog login.
var decodedUsername = userName.Replace("%40", "@");
var encodedPassword = password.Length > 0 ? Utility.HashString(password) : String.Empty;
var leapFrogUsers = LeapFrogUserData.FindAll(decodedUsername, encodedPassword);
if (leapFrogUsers.Count > 0)
{
return new User
{
Id = (uint)leapFrogUsers[0].Id,
Guid = leapFrogUsers[0].Guid
};
}
else
throw new HttpResponseException("Invalid login credentials");
}
}
Mogę przejść do myapi / api / users / i wywołać GetAll i mogę przejść do myapi / api / users / 1 i wywoła Get, jednak jeśli wywołam myapi / api / users / authentication? Username = {0} & password = {1} to wywoła Get (NOT Authenticate) i błąd:
Słownik parametrów zawiera wpis o wartości null dla parametru „id” typu „System.Int32” nie dopuszczającego wartości null dla metody „System.String Get (Int32)” w „Navtrak.Services.WCF.NavtrakAPI.Controllers.UsersController”. Opcjonalny parametr musi być typem referencyjnym, typem dopuszczającym wartość null lub być zadeklarowany jako parametr opcjonalny.
Jak mogę wywołać niestandardowe nazwy metod, takie jak Authenticate?
Odpowiedzi:
Domyślnie konfiguracja trasy jest zgodna z konwencjami RESTFul, co oznacza, że akceptuje tylko nazwy akcji Get, Post, Put i Delete (spójrz na trasę w global.asax => domyślnie nie pozwala określić żadnej nazwy akcji => używa czasownika HTTP do wysyłki). Więc kiedy wysyłasz do siebie żądanie GET
/api/users/authenticate
, w zasadzie wywołujeszGet(int id)
akcję i podajesz ją,id=authenticate
co oczywiście ulega awarii, ponieważ twoja akcja Get oczekuje liczby całkowitej.Jeśli chcesz mieć inne nazwy akcji niż standardowe, możesz zmodyfikować definicję trasy w
global.asax
:Teraz możesz przejść do,
/api/values/getauthenticate
aby uwierzytelnić użytkownika.źródło
{action}
tego ograniczenia{id}
, aby nic innego niżint
lubGuid
(lub cokolwiek) nie pasowało. Wtedy powinien być w stanie przejść do tego, który zasugerował DarinJest to najlepsza metoda, jaką do tej pory wymyśliłem, aby włączyć dodatkowe metody GET, jednocześnie obsługując również zwykłe metody REST. Dodaj następujące trasy do swojej konfiguracji WebApiConfig:
Sprawdziłem to rozwiązanie z poniższą klasą testową. Udało mi się pomyślnie trafić każdą metodę w moim kontrolerze poniżej:
Sprawdziłem, że obsługuje następujące żądania:
Zauważ, że jeśli twoje dodatkowe akcje GET nie zaczynają się od „Get”, możesz chcieć dodać atrybut HttpGet do metody.
źródło
put
i,delete
takie jak zrobiłeś,get
ipost
, czy też będzie działać dobrze?put
lubdelete
czasowników ponieważ wnioski te będą zazwyczaj towarzyszą parametr id do identyfikacji zasobu, który chcesz zastosować tę operację.delete
Wywołanie/api/foo
powinno wyrzucić błąd, ponieważ który foo starasz się usunąć? Dlatego trasa DefaultApiWithId powinna dobrze obsłużyć te przypadki.Jestem dniami w świecie MVC4.
Ze względu na swoją wartość mam SitesAPIController i potrzebowałem niestandardowej metody, którą można by nazwać:
Z różnymi wartościami ostatniego parametru, aby uzyskać rekord z różnymi dyspozycjami.
W końcu zadziałało dla mnie:
Metoda w SitesAPIController:
I to w pliku WebApiConfig.cs
Tak długo, jak nazywam {dyspozycję} jako {id}, z którą się spotykałem:
Kiedy zmieniłem jego nazwę na {disposition}, zaczęło działać. Najwyraźniej nazwa parametru jest dopasowywana do wartości w symbolu zastępczym.
Możesz edytować tę odpowiedź, aby była bardziej dokładna / wyjaśniająca.
źródło
Interfejs API sieci Web domyślnie oczekuje adresu URL w postaci api / {kontroler} / {id}, aby zastąpić ten domyślny routing. możesz ustawić routing na jeden z poniższych dwóch sposobów.
Pierwsza opcja:
Dodaj poniżej rejestrację trasy w WebApiConfig.cs
Udekoruj swoją metodę akcji za pomocą HttpGet i parametrów, jak poniżej
dla wywołania powyższej metody adres URL będzie taki jak poniżej
http: // localhost: [yourport] / api / MyData / ReadMyData? param1 = value1 & param2 = value2 & param3 = value3
Druga opcja Dodaj prefiks trasy do klasy kontrolera i Udekoruj swoją metodę akcji za pomocą HttpGet, jak poniżej. W takim przypadku nie trzeba zmieniać żadnego pliku WebApiConfig.cs. Może mieć routing domyślny.
dla wywołania powyższej metody adres URL będzie taki jak poniżej
http: // localhost: [yourport] / api / MyData / ReadMyData? param1 = value1 & param2 = value2 & param3 = value3
źródło
Jeśli używasz ASP.NET 5 z ASP.NET MVC 6 , większość z tych odpowiedzi po prostu nie zadziała, ponieważ zwykle pozwolisz MVC utworzyć dla Ciebie odpowiednią kolekcję tras (przy użyciu domyślnych konwencji RESTful), co oznacza, że nie znajdziesz żadnego
Routes.MapRoute()
wezwania do edycji do woli.ConfigureServices()
Metoda wywoływana przezStartup.cs
pliku zarejestruje MVC z ramami wstrzykiwania zależności wbudowanych w ASP.NET 5: w ten sposób, kiedy zadzwonićApplicationBuilder.UseMvc()
później w tej klasie, ramy MVC automatycznie doda tych tras domyślnych aplikacji. Możemy spojrzeć na to, co dzieje się za maską, patrząc naUseMvc()
implementację metody w kodzie źródłowym frameworka:Zaletą tego jest to, że framework obsługuje teraz całą ciężką pracę, iterując przez wszystkie akcje kontrolera i konfigurując ich domyślne trasy, oszczędzając w ten sposób trochę zbędnej pracy.
Złe jest to, że istnieje niewiele lub nie ma dokumentacji na temat dodawania własnych tras. Na szczęście możesz to łatwo zrobić, używając podejścia opartego na konwencji i / lub podejściu opartym na atrybutach (inaczej routing atrybutów ).
Oparte na konwencji
W swojej klasie Startup.cs zamień to:
z tym:
Oparte na atrybutach
Wspaniałą cechą MVC6 jest to, że można również definiować trasy dla poszczególnych kontrolerów, dekorując
Controller
klasę i / lubAction
metody odpowiednimi parametramiRouteAttribute
i / lubHttpGet
/HttpPost
szablonowymi, takimi jak następujące:Ten kontroler będzie obsługiwał następujące żądania:
Zauważ również, że jeśli użyjesz tych dwóch podejść jednocześnie, trasy oparte na atrybutach (jeśli zostaną zdefiniowane) zastąpią trasy oparte na Konwencji, a obie z nich zastąpią trasy domyślne zdefiniowane przez
UseMvc()
.Aby uzyskać więcej informacji, możesz również przeczytać następujący post na moim blogu.
źródło
public IActionResult Patch(int id, [FromQuery] Person person)
, wszystkie właściwości przychodzące są nieważne!Zobacz ten artykuł, aby uzyskać dłuższe omówienie nazwanych akcji. Pokazuje również, że możesz użyć atrybutu [HttpGet] zamiast poprzedzać nazwę akcji przedrostkiem „get”.
http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
źródło
Po prostu zmodyfikuj plik WebAPIConfig.cs, jak pokazano poniżej
Następnie zaimplementuj swoje API, jak poniżej
źródło
Web APi 2 i nowsze wersje obsługują nowy typ routingu, zwany routingiem atrybutów. Jak sama nazwa wskazuje, routing atrybutów używa atrybutów do definiowania tras. Routing atrybutów zapewnia większą kontrolę nad identyfikatorami URI w internetowym interfejsie API. Na przykład można łatwo utworzyć identyfikatory URI opisujące hierarchie zasobów.
Na przykład:
Idealnie sprawdzi się i nie potrzebujesz żadnego dodatkowego kodu np. W WebApiConfig.cs. Musisz tylko upewnić się, że routing interfejsu API sieci Web jest włączony lub nie w WebApiConfig.cs, jeśli nie, możesz aktywować jak poniżej:
Nie musisz robić nic więcej ani niczego zmieniać w WebApiConfig.cs. Aby uzyskać więcej informacji, zajrzyj do tego artykułu .
źródło