.Net Core API Microsoft.AspNet.Identity.Core - c#

My question.
So my question is how do I connect a .Net Core API using Microsoft.AspNetCore.Identity to an identity (AspNetUser) table created using .Net 4.5 and Microsoft.AspNet.Identity.Core
The Details.
I have a MVC web application that allows user to register an login, and view certain information based on there credentials. This was written in .Net4.5. and I'm assuming using Microsoft.AspNet.Identity.Core. (Which I think is the non .NET core version. ITs not the best naming convention) This project cant be changed.
I'm trying to extend some of the features such as login and register to use an API. I'm trying to build the API in .Net Core and Microsoft.AspNetCore.Identity;
I have created a simple test login controller.
[ApiController]
public class AuthController : ControllerBase
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly IConfiguration _config;
public AuthController(UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
IConfiguration config)
{
_userManager = userManager;
_signInManager = signInManager;
_config = config; ;
}
[HttpPost]
[AllowAnonymous]
public async Task<IActionResult> Login(LoginDto user)
{
if (ModelState.IsValid)
{
var testResult = await _signInManager.PasswordSignInAsync(user.Username, user.Password, false, false);
return Ok(testResult);
}
return BadRequest();
}
}
Originally I was getting invalid column errors, as it seems that the AspNetUsers table is now created with additional fields compared with the AspNetUsers table created by the .NET4.5 system.
I got round this issue by ignoring them in the ModelBuilderof the dbcontext class
{
public AuthConext(DbContextOptions<AuthConext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>().Ignore(c => c.PhoneNumberConfirmed)
.Ignore(c => c.TwoFactorEnabled)
.Ignore(c => c.SecurityStamp)
.Ignore(c => c.LockoutEnabled)
.Ignore(c => c.NormalizedEmail)
.Ignore(c => c.NormalizedUserName)
.Ignore(c => c.ConcurrencyStamp)
.Ignore(c => c.LockoutEnd);
}
}
However I'm not getting errors regarding the LINQ query.
.Where(i => i.NormalizedUserName == __normalizedUserName_0)' could not be translated. Additional information: Translation of member 'NormalizedUserName' on entity type 'IdentityUser' failed. This commonly occurs when the specified member is unmapped. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.<VisitMethodCall>g__CheckTranslated|15_0(ShapedQueryExpression translated, <>c__DisplayClass15_0& )
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, LambdaExpression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.FirstOrDefaultAsync[TSource](IQueryable`1 source, Expression`1 predicate, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9.FindByNameAsync(String normalizedUserName, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Identity.UserManager`1.FindByNameAsync(String userName)
at MyFirstChoice_Api_CORE.Controllers.AuthController.Login(LoginDto user) in C:\Repos\MyFirstChoice_Api_CORE\MyFirstChoice_Api_CORE\Controllers\AuthController.cs:line 43
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
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)
While it does suggest a solution. I'm not sure where to make that change as I'm not creating a query myself just simply calling _signInManager.PasswordSignInAsync.
So my question is how to I connect and .Net Core API using Microsoft.AspNetCore.Identity to and identity table created using .net 4.5 and Microsoft.AspNet.Identity.Core

Microsoft.AspNetCore.Identity and Microsoft.AspNet.Identity.Core seem to not have a lot in common
What is the difference between Microsoft.AspNet.Identity.Core and Microsoft.AspNetCore.Identity?
However Microsoft.AspNetCore.Identity is a .net standard library so it should be compatible with .net core / 5 apps
So you should just try to use it in your web api
https://www.c-sharpcorner.com/article/authentication-and-authorization-in-asp-net-core-web-api-with-json-web-tokens/

Related

.NET 6 API System.InvalidOperationException

I have Autofac module like this on one class;
public class AutofacBusinessModule:Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ProductManager>().As<IProductService>();
builder.RegisterType<EfProductDal>().As<IProductDal>();
builder.RegisterType<CategoryManager>().As<ICategoryService>();
builder.RegisterType<EfCategoryDal>().As<ICategoryDal>();
builder.RegisterType<CustomerManager>().As<ICustomerService>();
builder.RegisterType<EfCustomerDal>().As<ICustomerDal>();
builder.RegisterType<RegionManager>().As<IRegionService>();
builder.RegisterType<EfRegionDal>().As<IRegionDal>();
builder.RegisterType<TerritoryManager>().As<ITerritoryService>();
builder.RegisterType<EfTerritoryDal>().As<ITerritoryDal>();
builder.RegisterType<ShipperManager>().As<IShipperService>();
builder.RegisterType<EfShipperDal>().As<IShipperDal>();
builder.RegisterType<EmployeeManager>().As<IEmployeeDal>();
builder.RegisterType<EfEmployeeDal>().As<IEmployeeDal>();
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces()
.EnableInterfaceInterceptors(new ProxyGenerationOptions()
{
Selector = new AspectInterceptorSelector()
}).SingleInstance();
}
my api code its there;
[Route("api/[controller]")]
[ApiController]
public class ProductsController : Controller
{
private readonly IProductService _productService;
public ProductsController(IProductService productService)
{
_productService = productService;
}
[HttpGet("getall")]
public IActionResult GetAllProducts()
{
var result = _productService.GetAll();
if (result.Success)
{
return Ok(result);
}
return BadRequest(result);
}
}
}
I add this on program.cs but didn't work, if lower I use .net 6 i fix it like that but i dont know how to fix .net 6 because startup doesnt exists anymore.
IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule(new AutofacBusinessModule());
});
How can I fix this?
it gives me that error
System.InvalidOperationException: Unable to resolve service for type 'TAO.Business.Abstract.IProductService' while attempting to activate 'TAO.WebApi.Controllers.ProductsController'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method3(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass7_0.b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
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: */*
Connection: keep-alive
Host: localhost:7019
User-Agent: PostmanRuntime/7.30.0
Accept-Encoding: gzip, deflate, br
Postman-Token: fbff062e-ca49-4f37-afc5-e8785afbd43c
Try the following code from migration doc:
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
// Register services directly with Autofac here. Don't
// call builder.Populate(), that happens in AutofacServiceProviderFactory.
builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.RegisterModule(new AutofacBusinessModule()));
Note that the "old" generic hosting model still works in .NET 6, there is no requirement to use the new minimal hosting model (but you need to copy not only CreateHostBuilder method but also contents of old Program.Main into the new Program top-level statement file).

EF Core 6 + Odata: Calculate total count: Nullable object must have a value error

I'm trying to retrieve the grouped rows from the SQL view with using OData filters. The problem is, I'm getting the exception when the CountAsync for calculating the total rows based on the search criteria is being executed (the 2nd line in the FilterAsync method). The 1st line retrieves 10 rows, so the query works fine.
it does not matter whether I use any filters or not, the result is the same
url
http://localhost:9081/api/customer
DbContext Definition
public class MyDbContext : DbContext
{
public DbSet<DetailedCustomerView> list_detailed_customers { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<DetailedCustomerView>()
.ToView("list_detailed_customers")
.HasKey(t => t.CustomerId);
}
}
view entity
public class DetailedCustomerView
{
[Column("customer_id")]
public Int64 CustomerId { get; set; }
[Column("group_id")]
public Int64 GroupId { get; set; }
}
usage
dbContext.list_detailed_customers
.GroupBy(x => x.CustomerId)
.Select(cusromerGroup => new CustomerDetailedListDto
{
CustomerId = cusromerGroup.First().CustomerId,
GroupIds = cusromerGroup.Select(x => x.GroupId)
})
.FilterAsync(request.Options, cancellationToken);
CustomerDetailedListDto definition
public struct CustomerDetailedListDto
{
public Int64 CustomerId { get; set; }
public IEnumerable<Int64> GroupIds { get; set; }
}
ODataFilter extension
public static async Task<QueryResult<T>> FilterAsync<T>(this IQueryable<T> query, ODataQueryOptions options, CancellationToken cancellationToken)
{
List<T> items = await query.ApplyTo(options, AllowedQueryOptions.None).ToListAsync(cancellationToken);
Int32 totalCount = await query.ApplyTo(options, AllowedQueryOptions.Skip | AllowedQueryOptions.Top | AllowedQueryOptions.OrderBy).CountAsync(cancellationToken);
return new QueryResult<T>(items, totalCount);
}
The View list_detailed_customers definition (a simplified version)
SELECT
1 AS customer_id,
1 AS group_id
FROM customer t
UNION
SELECT
1 AS customer_id,
2 AS group_id
FROM customer
generated query when retrieving the rows
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 6.0.6 initialized 'MyDbContext' using provider 'Npgsql.EntityFrameworkCore.PostgreSQL:6.0.5+9d79af6e2586d5d28da253ac075706a5575a1743' with options: MaxPoolSize=1024
warn: Microsoft.EntityFrameworkCore.Query[10102]
The query uses a row limiting operator ('Skip'/'Take') without an 'OrderBy' operator. This may lead to unpredictable results. If the 'Distinct' operator is used after 'OrderBy', then make sure to use the 'OrderBy' operator after 'Distinct' as the ordering would otherwise get erased.
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (80ms) [Parameters=[#__TypedProperty_0='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SELECT t.c, t.customer_id, l1.group_id, l1.customer_id
FROM (
SELECT (
SELECT l0.customer_id
FROM list_detailed_customers AS l0
WHERE l.customer_id = l0.customer_id
LIMIT 1) AS c, l.customer_id
FROM list_detailed_customers AS l
GROUP BY l.customer_id
LIMIT #__TypedProperty_0
) AS t
LEFT JOIN list_detailed_customers AS l1 ON t.customer_id = l1.customer_id
ORDER BY t.customer_id
For calculating the total count number, I don't see any generated sql query
Stack trace with error message
Critical error occured: Nullable object must have a value.
at System.Nullable`1.get_Value()
at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.ClientProjectionRemappingExpressionVisitor.Visit(Expression expression)
at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.ClientProjectionRemappingExpressionVisitor.Visit(Expression expression)
at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.ApplyProjection(Expression shaperExpression, ResultCardinality resultCardinality, QuerySplittingBehavior querySplittingBehavior)
at Microsoft.EntityFrameworkCore.Query.Internal.SelectExpressionProjectionApplyingExpressionVisitor.VisitExtension(Expression extensionExpression)
at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryTranslationPostprocessor.Process(Expression query)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_0`1.<ExecuteAsync>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ExecuteAsync[TSource,TResult](MethodInfo operatorMethodInfo, IQueryable`1 source, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.CountAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at MyProject.Lib.OData.FilterExtension.FilterAsync[T](IQueryable`1 query, ODataQueryOptions options, CancellationToken cancellationToken)
at MyProject.Core.Mediator.Dispatching.Dispatcher.Dispatch[TResponse](IRequest`1 request, CancellationToken cancellationToken)
at Web.Controllers.CustomerController.GetList(ODataQueryOptions options)
at lambda_method2589(Closure , Object )
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at NSwag.AspNetCore.Middlewares.SwaggerUiIndexMiddleware.Invoke(HttpContext context)
at NSwag.AspNetCore.Middlewares.RedirectToIndexMiddleware.Invoke(HttpContext context)
at NSwag.AspNetCore.Middlewares.OpenApiDocumentMiddleware.Invoke(HttpContext context)
at MyProject.Core.Web.Middlewares.HeadersHandlerMiddleware.Invoke(HttpContext httpContext)
at MyProject.Core.Web.Middlewares.ExceptionHandlerMiddleware.Invoke(HttpContext httpContext)
EF Core version: 6.0.6.0
Database provider:
Npgsql.EntityFrameworkCore.PostgreSQL:6.0.5
Microsoft.AspNetCore.OData 8.0.11
Target framework: NET 7.0
Operating system: Windows 11

throw user defined exception message when an unregistered dependency is resolved

I have 1 service like below
public interface IGopalSharma
{
}
Now, if I forgot the implementation of this interface IGopalSharma and use this service in constructor as below
private readonly IGopalSharma _gopalSharma;
public ClientsController(IGopalSharma gopalSharma)
{
_gopalSharma = gopalSharma ?? throw new ArgumentNullException(
"An implementation of IGopalSharma must be provided");
}
So I want to return this "An implementation of IGopalSharma must be provided" msg.
but something different is coming.
System.InvalidOperationException: Unable to resolve service for type 'SAPI.Services.Interface.IGopalSharma' while attempting to activate 'SAPI.API.Controllers.ClientsController'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method9(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass7_0.<CreateActivator>b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
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)
I want custom msg here. How can I do it?

Unable to resolve service DbContext while attempting to activate controller

I have my own DbContext:
public class DreamsContext : DbContext
{
public DbSet<UserAccount> UserAccounts { get; set; }
public DbSet<DreamPublication> DreamPublications { get; set; }
public DreamsContext(DbContextOptions<DreamsContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserAccount>().ToTable("dreams_user");
modelBuilder.Entity<DreamPublication>().ToTable("dream_publications");
base.OnModelCreating(modelBuilder);
}
}
where UserAccount and DreamPublication contain just a few fields with get and set.
In my startup I add this for the DbContext:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<Models.DreamsContext>(options =>
options.UseSqlServer("server = SCAT\\SQLEXPRESS; database = dreams_web; Trusted_Connection=True ; MultipleActiveResultSets = true"));
}
And then I'm trying to inject my DbContext into a controller using DI:
private readonly Models.DreamsContext _context;
public SignUpController (Models.DreamsContext dbContext)
{
_context = dbContext;
}
But when I am trying to do something with this context I get an exception:
Unable to resolve service for type '(My DbContext)' while attempting to activate '(My controller)'
And I don't know what to do, on MSDN they do just this and everything works
Update. This is what written in console
System.InvalidOperationException: Unable to resolve service for type 'DreamWeb.Models.DreamsContext' while attempting to activate 'DreamWeb.Controllers.SignUpController'.
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.GetService(IServiceProvider sp, Type type, Type requiredBy, Boolean isDefaultParameterRequired)
at lambda_method25(Closure , IServiceProvider , Object[] )
at Microsoft.AspNetCore.Mvc.Controllers.ControllerActivatorProvider.<>c__DisplayClass7_0.<CreateActivator>b__0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
The main problem was I was trying to configure services in Startup class, while I am using asp.net CORE so the main magic is going in program.cs
I moved everything to program.cs and everything is working fine. It cost me a few days, even it's such a little mistake
https://learn.microsoft.com/en-us/dotnet/architecture/porting-existing-aspnet-apps/app-startup-differences
According to this, startup should continue to work in asp.net core, but i had problems with it
I had the same problem I solved by adding the connection to the db in the main file of the Project Program.cs , add it after the line var builder :
// db connection
builder.Services.AddDbContext<Dbcontexclass>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnectionString"));
Add in appsettings.json :
"ConnectionStrings": {
"DefaultConnectionString": "SERVER=server;DATABASE=database;User ID=user;PASSWORD=password;"
}
fill the Connection String , Dbcontexclass , and it should work, I leave you the docs link ( https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/working-with-sql?view=aspnetcore-7.0&tabs=visual-studio )

SassKit.Multitenancy not compatible with AspNetCore 2.2?

I've created a .NET Core API Controller, and in the POST method, I'm trying to use the CreatedAtActionResult method to include the route as a Location Header in my response.
[ApiController, Route("v1/[controller]")]
public class WidgetController: ControllerBase
{
public WidgetController(IWidgetService service)
{
_service = service;
}
private readonly IWidgetService _service;
[HttpGet("{id}", Name = "GetSingle")]
public IActionResult GetSingle(Guid id)
{
var result = _service.Get(id);
return Ok(result);
}
[HttpPost]
public IActionResult Post(WidgetModel model)
{
var result = _service.Post(model);
return result == Guid.Empty
? (IActionResult) BadRequest("No changes saved.")
: CreatedAtAction(nameof(GetSingle),
new {id = result},
model);
}
}
When I start the application, the first call to POST from POSTman runs without problem. Both the object and the Location Header URL get generated as expected. However, if I try to hit that endpoint a second time while the code is still running, I get the following error:
System.InvalidOperationException: No service for type 'Microsoft.AspNetCore.Routing.IEndpointAddressScheme1[Microsoft.AspNetCore.Routing.RouteValuesAddress]' has been registered.
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.AspNetCore.Routing.DefaultLinkGenerator.GetEndpoints[TAddress](TAddress address)
at Microsoft.AspNetCore.Routing.DefaultLinkGenerator.GetPathByAddress[TAddress](HttpContext httpContext, TAddress address, RouteValueDictionary values, RouteValueDictionary ambientValues, Nullable1 pathBase, FragmentString fragment, LinkOptions options)
at Microsoft.AspNetCore.Routing.LinkGeneratorRouteValuesAddressExtensions.GetPathByRouteValues(LinkGenerator generator, HttpContext httpContext, String routeName, Object values, Nullable1 pathBase, FragmentString fragment, LinkOptions options)
at Microsoft.AspNetCore.Mvc.Routing.EndpointRoutingUrlHelper.Action(UrlActionContext urlActionContext)
at Microsoft.AspNetCore.Mvc.UrlHelperExtensions.Action(IUrlHelper helper, String action, String controller, Object values, String protocol, String host, String fragment)
at Microsoft.AspNetCore.Mvc.UrlHelperExtensions.Action(IUrlHelper helper, String action, String controller, Object values, String protocol, String host)
at Microsoft.AspNetCore.Mvc.CreatedAtActionResult.OnFormatting(ActionContext context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsync(ActionContext context, ObjectResult result)
at Microsoft.AspNetCore.Mvc.ObjectResult.ExecuteResultAsync(ActionContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultFilters()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
at SaasKit.Multitenancy.Internal.TenantResolutionMiddleware1.Invoke(HttpContext context, ITenantResolver`1 tenantResolver)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
I have tried swapping out the CreatedAtAction with an Ok, and that 200 result will return as many times as I click the button in POSTman.
The code inside the Post method successfully processes, and it will move onto the OnActionExecuted method of a Filter that I created. I've tried looking through all of the properties of the ActionExecutedContext object and I don't see anything out of the ordinary. Once I get out of that empty OnActionExecuted method, the call returns the 500 status code and the above stack trace inside the error page. I do have an Exception filter, but that doesn't get touched.
Has anyone had issues with this before?
For reference, here is my Startup Configuration:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddMultitenancy<AppTenant, CachingAppTenantResolver>();
services.AddAutoMapper()
.AddSingleton(ConfigureAutoMapper())
.AddMvc(options =>
{
options.Filters.Add<ValidatorActionFilter>();
options.Filters.Add<ErrorHandlingFilter>();
})
.AddFluentValidation(validation => {
validation.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
validation.ImplicitlyValidateChildProperties = true;
validation.RegisterValidatorsFromAssemblyContaining<WidgetModelValidator>();
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.ConfigureApiBehaviorOptions(options =>
{
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
});
services.AddEntityFrameworkSqlServer()
.AddDbContext<MyContext>();
services.Configure<MultitenancyOptions>(configuration.GetSection("Multitenancy"));
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins("http://localhost:4200").AllowAnyHeader().AllowAnyMethod();
});
});
ConfigureContainer(container);
return provider;
}
Try setting CompatibilityVersion.Version_2_0 or 2.1 instead of 2.2?
EndpointRouting is quite a big change under the covers of 2.2, and your 3rd party add-on might not be compatible.
Setting compatibility back to 2.1 will typically not require any code changes in your controller, so it's fairly low-cost.

Categories

Resources