.NET 6 API System.InvalidOperationException - c#

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).

Related

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 )

.Net Core API Microsoft.AspNet.Identity.Core

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/

NullReferenceException from JsonSerializer in POST method

I'm trying to write a simple REST API in #C, but I ran into a problem with a rather unhelpful error message very early when writing a POST handler. I'm using .NET Core 3.0 and the project was created with the ASP.NET Core API template in Visual Studio.
This is a simplified version of my code that still triggers the issue (the classes are in separate Files in the full project):
[Route("api/blub")]
[ApiController]
public class BlubController : ControllerBase
{
[HttpGet]
public IEnumerable<Blub> Get()
{
return new Blub[0];
}
[HttpPost]
public ActionResult<Blub> PostBlub([FromBody] string[] paths)
{
return new Blub(paths);
}
}
public class Blub
{
public Blub(string[] paths)
{
this.Paths = paths;
StartedAt = DateTime.Now;
}
public string[] Paths { get; }
public DateTime StartedAt { get; }
}
The payload of my POST request is something like the following:
{ "paths": [ "abc", "def" ] }
I'm getting the following Exception when performing a POST request to my api/blub route:
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Text.Json.JsonSerializer.HandleStartObject(JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadCore(JsonSerializerOptions options, Utf8JsonReader& reader, ReadStack& readStack)
at System.Text.Json.JsonSerializer.ReadCore(JsonReaderState& readerState, Boolean isFinalBlock, ReadOnlySpan`1 buffer, JsonSerializerOptions options, ReadStack& readStack)
at System.Text.Json.JsonSerializer.ReadAsync[TValue](Stream utf8Json, Type returnType, JsonSerializerOptions options, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.Formatters.SystemTextJsonInputFormatter.ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BodyModelBinder.BindModelAsync(ModelBindingContext bindingContext)
at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value)
at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>c__DisplayClass0_0.<<CreateBinderDelegate>g__Bind|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
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.<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__Logged|17_1(ResourceInvoker invoker)
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)
It doesn't matter whether my POST request contains the correct body or not, any POST requests seems to trigger this exception. The GET request works without issues. I tried to log to the console and set a breakpoint in my function, but as far as I can tell the exception is thrown even before my function is called.
Why is the JsonFormatter throwing an exception here, and how can I fix this?
You have an issue in type mapping, either change method signature to:
[HttpPost]
public ActionResult<Blub> PostBlub([FromBody] MyRequest request)
{
return new Blub(request.Paths);
}
public class MyRequest
{
public string[] Paths { get; set; }
}
Or change the payload to:
[ "abc", "def" ]
This simply means that some member/variable of some reference type
is dereferenced by using and of its instance non-static members,
which requires this member/variable to be non-null, but in fact it
appears to be null. Simply if it execute it under debugger, it will
stop the execution where the exception is thrown. Put a break point on
that line, restart the application and come to this point again.
Evaluate all references involved in next line and see which one is
null while it needs to be not null. After you figure this out, fix the
code: either make sure the member/variable is properly initialized to
a non-null reference, or check it for null and, in case of null,
do something else.
Use the below code snippet:
[HttpPost]
public ActionResult<Blub> PostBlub([FromBody] APIRequest request)
{
return new Blub(request.Paths);
}
public class APIRequest
{
public string[] Paths { get; set; }
}

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