Estou convertendo da API Web do WCF para a nova API Web ASP.NET MVC 4. Eu tenho um UsersController e quero um método chamado Authenticate. Vejo exemplos de como fazer GetAll, GetOne, Post e Delete, mas e se eu quiser adicionar métodos extras a esses serviços? Por exemplo, meu UsersService deve ter um método chamado Authenticate onde eles passam um nome de usuário e senha, mas não funciona.
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");
}
}
Posso navegar para myapi / api / users / e ele chamará GetAll e posso navegar para myapi / api / users / 1 e chamará Get, no entanto, se eu chamar myapi / api / users / authenticate? Username = {0} & senha = {1} então chamará Get (NOT Authenticate) e erro:
O dicionário de parâmetros contém uma entrada nula para o parâmetro 'id' do tipo não anulável 'System.Int32' para o método 'System.String Get (Int32)' em 'Navtrak.Services.WCF.NavtrakAPI.Controllers.UsersController'. Um parâmetro opcional deve ser um tipo de referência, um tipo anulável ou ser declarado como um parâmetro opcional.
Como posso chamar nomes de métodos personalizados, como Authenticate?
Respostas:
Por padrão, a configuração da rota segue as convenções RESTFul, o que significa que ela aceitará apenas os nomes de ação Get, Post, Put e Delete (veja a rota em global.asax => por padrão, ela não permite que você especifique nenhum nome de ação => usa o verbo HTTP para despachar). Então, quando você envia uma solicitação GET,
/api/users/authenticate
basicamente chama aGet(int id)
ação e passa, oid=authenticate
que obviamente trava porque sua ação Get espera um número inteiro.Se quiser ter nomes de ação diferentes dos padrões, você pode modificar sua definição de rota em
global.asax
:Agora você pode navegar
/api/values/getauthenticate
para autenticar o usuário.fonte
{action}
que tenha uma restrição em{id}
para que qualquer coisa diferente deint
ouGuid
(ou qualquer outra) não coincidisse. Em seguida, deve ser capaz de cair para o sugerido por DarinEste é o melhor método que desenvolvi até agora para incorporar métodos GET extras ao mesmo tempo que oferece suporte aos métodos REST normais. Adicione as seguintes rotas ao seu WebApiConfig:
Eu verifiquei essa solução com a classe de teste abaixo. Consegui acertar com sucesso cada método em meu controlador abaixo:
Verifiquei que ele suporta as seguintes solicitações:
Observe que se suas ações GET extras não começarem com 'Get', você pode adicionar um atributo HttpGet ao método.
fonte
put
edelete
como você fez emget
epost
, vai funcionar bem também?put
oudelete
já que essas solicitações normalmente acompanhariam um parâmetro id para identificar o recurso ao qual deseja aplicar essa operação. Umadelete
chamada para/api/foo
deve gerar um erro, pois qual foo você está tentando excluir? Portanto, a rota DefaultApiWithId deve lidar bem com esses casos.Estou dias no mundo MVC4.
Pelo que vale a pena, eu tenho um SitesAPIController e precisava de um método personalizado, que poderia ser chamado assim:
Com valores diferentes para o último parâmetro obter registro com disposições diferentes.
O que finalmente funcionou para mim foi:
O método no SitesAPIController:
E isso no WebApiConfig.cs
Por enquanto eu estava nomeando a {disposition} como {id} eu estava encontrando:
Quando mudei o nome para {disposition}, ele começou a funcionar. Portanto, aparentemente, o nome do parâmetro corresponde ao valor no marcador.
Sinta-se à vontade para editar esta resposta para torná-la mais precisa / explicativa.
fonte
A API da Web por padrão espera URL na forma de api / {controller} / {id}, para substituir este roteamento padrão. você pode definir o roteamento com qualquer uma das duas maneiras abaixo.
Primeira opção:
Adicione o registro de rota abaixo em WebApiConfig.cs
Decore seu método de ação com HttpGet e parâmetros como abaixo
para chamar o método acima, o url será como abaixo
http: // localhost: [yourport] / api / MyData / ReadMyData? param1 = valor1 & param2 = valor2 & param3 = valor3
Segunda opção Adicionar prefixo de rota à classe Controller e decorar seu método de ação com HttpGet como abaixo. Nesse caso, não é necessário alterar nenhum WebApiConfig.cs. Ele pode ter roteamento padrão.
para chamar o método acima, o url será como abaixo
http: // localhost: [yourport] / api / MyData / ReadMyData? param1 = valor1 & param2 = valor2 & param3 = valor3
fonte
Caso você esteja usando ASP.NET 5 com ASP.NET MVC 6 , a maioria dessas respostas simplesmente não funcionará porque você normalmente deixará o MVC criar a coleção de rotas apropriada para você (usando as convenções RESTful padrão), o que significa que você não encontrará nenhuma
Routes.MapRoute()
chamada para editar à vontade.O
ConfigureServices()
método invocado peloStartup.cs
arquivo registrará MVC com o framework Dependency Injection embutido na ASP.NET 5: dessa forma, quando você chamarApplicationBuilder.UseMvc()
posteriormente nessa classe, o framework MVC adicionará automaticamente essas rotas padrão ao seu aplicativo. Podemos dar uma olhada no que acontece nos bastidores, observando aUseMvc()
implementação do método dentro do código-fonte do framework:O bom disso é que o framework agora lida com todo o trabalho pesado, iterando por meio de todas as ações do controlador e configurando suas rotas padrão, poupando assim a você algum trabalho redundante.
O ruim é que há pouca ou nenhuma documentação sobre como você pode adicionar suas próprias rotas. Felizmente, você pode fazer isso facilmente usando uma abordagem baseada em convenção e / ou baseada em atributos (também conhecida como roteamento de atributos ).
Baseado em convenção
Em sua classe Startup.cs, substitua este:
com isso:
Baseado em Atributos
Uma grande coisa sobre MVC6 é que você também pode definir rotas em uma base por controlador, decorando a
Controller
classe e / ou osAction
métodos com os parâmetros apropriadosRouteAttribute
e / ouHttpGet
/HttpPost
modelo, como o seguinte:Este controlador irá lidar com as seguintes solicitações:
Observe também que se você usar as duas abordagens juntas, as rotas baseadas em atributos (quando definidas) substituirão as baseadas em convenção, e ambas substituirão as rotas padrão definidas por
UseMvc()
.Para mais informações, você também pode ler a seguinte postagem no meu blog.
fonte
public IActionResult Patch(int id, [FromQuery] Person person)
, todas as propriedades recebidas são nulos!Consulte este artigo para uma discussão mais longa sobre ações nomeadas. Também mostra que você pode usar o atributo [HttpGet] em vez de prefixar o nome da ação com "get".
http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
fonte
Apenas modifique seu WebAPIConfig.cs conforme abaixo
Em seguida, implemente sua API conforme abaixo
fonte
Web APi 2 e versões posteriores suportam um novo tipo de roteamento, chamado roteamento de atributo. Como o nome indica, o roteamento de atributo usa atributos para definir rotas. O roteamento de atributos oferece mais controle sobre os URIs em sua API da web. Por exemplo, você pode criar facilmente URIs que descrevem hierarquias de recursos.
Por exemplo:
Será perfeito e você não precisa de nenhum código extra, por exemplo, em WebApiConfig.cs. Você só precisa ter certeza de que o roteamento da API da web está habilitado ou não no WebApiConfig.cs, se não você pode ativar como abaixo:
Você não precisa fazer nada mais ou alterar algo em WebApiConfig.cs. Para mais detalhes você pode dar uma olhada neste artigo .
fonte