I am implementing Jwt in my webApi and it generates an error when calling the route, in my controller is the code that generates the token and also the other services with the Authorize in each one until I generate the token that allows me to use the services, what would be my mistake that I am committing? Why does it give me that error in postman? I also don't know whether to create another controller and then put the code of the token and the other services in another controller with Authorize, will there be no problem?
this is the error i get in postman
System.InvalidOperationException: Multiple constructors accepting all given argument types have been found in type 'AjiPu.Controllers.ClienteController'. There should only be one applicable constructor.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.TryFindMatchingConstructor(Type instanceType, Type[] argumentTypes, ConstructorInfo& matchingConstructor, Nullable`1[]& parameterMap)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.FindApplicableConstructor(Type instanceType, Type[] argumentTypes, ConstructorInfo& matchingConstructor, Nullable`1[]& matchingParameterMap)
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.CreateFactory(Type instanceType, Type[] argumentTypes)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.CreateActivator(ControllerActionDescriptor descriptor)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.CreateControllerFactory(ControllerActionDescriptor descriptor)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvokerCache.GetCachedResult(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvokerProvider.OnProvidersExecuting(ActionInvokerProviderContext context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionInvokerFactory.CreateInvoker(ActionContext actionContext)
at Microsoft.AspNetCore.Mvc.Routing.ActionEndpointFactory.<>c__DisplayClass7_0.<CreateRequestDelegate>b__0(HttpContext context)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
HEADERS
=======
Accept: */*
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 51
Content-Type: application/json
Host: localhost:44397
User-Agent: PostmanRuntime/7.26.8
Postman-Token: fd759aab-b1d9-46ea-b627-50908eb97c40
this is my controller
using AjiPu.Data;
using AjiPu.Models;
using JWTAuthDemo.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
namespace AjiPu.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ClienteController : ControllerBase
{
//context de la base de datos
private readonly SVMQASContext _context;
public ClienteController(SVMQASContext context)
{
_context = context;
}
private IConfiguration _config;
//llamamos al configuration
public ClienteController(IConfiguration config)
{
_config = config;
}
//Login que genera el token
[HttpPost]
public IActionResult Login([FromBody] UserModel login)
{
IActionResult response = Unauthorized();
var user = AuthenticateUser(login);
if (user != null)
{
var tokenStr = GenerateJSONWebToken(user);
response = Ok(new { token = tokenStr });
}
return response;
}
private UserModel AuthenticateUser(UserModel login)
{
UserModel user = null;
if (login.UserName == "123" && login.Password == "123")
{
user = new UserModel { UserName = "AshprogHelp", EmailAddres = "[email protected]", Password = "123" };
}
return user;
}
private string GenerateJSONWebToken(UserModel userinfo)
{
var securutyKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var credentials = new SigningCredentials(securutyKey, SecurityAlgorithms.HmacSha256);
var claims = new[]
{
new Claim(JwtRegisteredClaimNames.Sub,userinfo.UserName),
new Claim(JwtRegisteredClaimNames.Email,userinfo.EmailAddres),
new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString())
};
var token = new JwtSecurityToken(
issuer: _config["Jwt:Issuer"],
audience: _config["Jwt:Issuer"],
claims,
expires: DateTime.Now.AddMinutes(120),
signingCredentials: credentials);
var encodetoken = new JwtSecurityTokenHandler().WriteToken(token);
return encodetoken;
}
// GET: api/<ClienteController>
[Authorize]
[HttpGet]
[Route("listaCliente")]
public ActionResult Get()
{
var data = from clientes in _context.UgvmaPerfilClientes select clientes;
return Ok(data);
//return Ok(_context.UgvmaPerfilClientes.ToList());
}
// GET api/<ClienteController>/5
//[Route("buscarCliente")]
[Authorize]
[HttpGet("buscar/{id}")]
public ActionResult Get(int id)
{
var data = from cliente in _context.UgvmaPerfilClientes
where cliente.Id.Equals(id)
select cliente;
return Ok(data);
}
// PUT api/<ClienteController>/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/<ClienteController>/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
The problem is in the dependency injection, as there are two constructors in the class and both expect a dependency, the injector cannot do its job since it can only call one constructor to create the object and that produces the error.
That is solved by receiving both dependencies in the same constructor: