Web api with two gets that do different actions - c#

I have two get statements in a controller
[HttpGet("{projectId:int}")]
public async Task<ActionResult<Models.Project>> GetById(int projectId)
{
var project = await _context.Projects.FindAsync(projectId);
if (project == null)
{
return NotFound();
}
return project;
}
// GET: api/project/5
[HttpGet("{projectCode}")]
public async Task<ActionResult<Project>> GetProjectByProjectCode(string projectCode)
{
var projects = await _context.Projects.FindAsync(projectCode);
if (projects == null)
{
return NotFound();
}
return projects;
}
The first get works perfectly and does what it is supposed to do pass in an ID and return the project associated with that ID
The second get does not work like it is supposed to. What it is supposed to do is pass in a projectCode parameter (string) and return the project associated with that project code.
The project codes are formatted like this --7000316139.13.01-- so that is why I am passing it using a string parameter
When I run the api with swagger I get the following error
System.ArgumentException: The key value at position 0 of the call to 'DbSet.Find' was of type 'string', which does not match the
property type of 'int'. at
Microsoft.EntityFrameworkCore.Internal.EntityFinder1.FindTracked(Object[] keyValues, IReadOnlyList1& keyProperties) at
Microsoft.EntityFrameworkCore.Internal.EntityFinder1.FindAsync(Object[] keyValues, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.FindAsync(Object[]
keyValues) at
Mcr.PRT.PM.Service.Controllers.ProjectController.GetProjectByProjectCode(String
projectCode) in
C:\Users\MaxGay\Source\Repos\PRT2\ProjectManagementService\Controllers\ProjectController.cs:line
98 at lambda_method(Closure , Object ) at
Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
at
Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper
mapper, ObjectMethodExecutor executor, Object controller, Object[]
arguments) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker
invoker, ValueTask`1 actionResultValueTask) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.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 where exception was thrown --- at
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_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 where exception was thrown --- 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
Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext
httpContext) at
Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext
httpContext, ISwaggerProvider swaggerProvider) at
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext
context) at
Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.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: text/plain Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9 Host: localhost Referer:
https://localhost/index.html User-Agent: Mozilla/5.0 (Windows NT 10.0;
Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83
Safari/537.36 Edg/85.0.564.41 :method: GET :authority: localhost
:scheme: https :path: /api/Project/7000316139.13.01 sec-fetch-site:
same-origin sec-fetch-mode: cors sec-fetch-dest: empty
I am not sure what the error is and why it is happening?
I have tried to switch the GetProjectsByProjectCode to public IActionResult but that did not help either

As ChiefTwoPencils pointed out the issue here is the primary key is an int and I am passing a string. I think I should probably get some sleep

Related

Get request throws a NullReference Exception only at the back-end

I'm Trying to make a get Request
[HttpGet]
public async Task<IActionResult> GetOrders()
{
int marketingId =
int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value);
var orders = await _repo.GetMarketeerOrders(marketingId);
var ordersToReturn = _mapper.Map<IEnumerable<MarketeerOrdersDto>>
(orders);
return Ok(ordersToReturn);
}
and this is GetMarketeerOrders Function
public async Task<IEnumerable<OrderDetails>> GetMarketeerOrders(int id)
{
var orders = await _context.OrderDetails.Include(i =>
i.Option).ThenInclude(i => i.Product).Include(i => i.Order).ThenInclude(i =>
i.Bill).Where(i => i.Order.MarketingId == id).OrderBy(i =>
i.Order.OrderDate).ToListAsync();
return orders;
}
but it throws the following exception when making the request, in my case I'm using Swagger UI
System.NullReferenceException: Object reference not set to an instance of an object.
at API.Controllers.MarketeerOrdersController.GetOrders() in /Users/ahmedgamal/projects/Drop Shipping/API/Controllers/MarketeerOrdersController.cs:line 27
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(ActionContext actionContext, 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.<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.Authentication.AuthenticationMiddleware.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.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
HEADERS
=======
Accept: */*
Connection: keep-alive
Host: localhost:5000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Referer: http://localhost:5000/swagger/index.html
sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Response headers
content-type: text/plain; charset=utf-8
date: Mon,06 Feb 2023 13:34:48 GMT
server: Kestrel
It comes to this line of code when debugging
int marketingId = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value);
Then it stops and throws the exception
But when using the same request from the client-side using angular and subscribe it by storing the response into some variable like this
ngOnInit(): void {
this.marketeeerOrdersservice.getOrders().subscribe(d =>{
this.allOrders = d;
});
}
and this is the getOrders Method
getOrders(){
return this.http.get<MarketeerOrders[]>(this.url);
}
Then there is no problem at all
What is the reason I can't figure it out
Is it because I should always store the response in a variable ?
I don't think so because other requests work properly without having to do this
The issue is that LocalStorage where i've stored my token is a frontend concept. It is accessible to JavaScript running in the browser. asp.net resides on backend and can not access the LocalStorage directly.
You'd need to access it through the scripts running in frontend which can communicate with backend using Ajax requests.

Data8.PowerPlatform.Dataverse.Client OnPremiseClient On Linux

I've implemented dynamics 365 sdk using Data8.PowerPlatform.Dataverse.Client with OnPremiseClient. It works on windows platform perfectly.
But when I deployed it on linux server using docker image mcr.microsoft.com/dotnet/aspnet:7.0 which uses Debian 11 Bullseye it requires to install gss-ntlmssp package.
I installed it on the image but when I want to make use of the service the error with bellow stacktrace happens:
System.NullReferenceException: Object reference not set to an instance of an object.
at System.Net.Security.SafeDeleteNegoContext.Dispose(Boolean disposing)
at System.Runtime.InteropServices.SafeHandle.Dispose()
at System.Net.Security.SafeDeleteNegoContext..ctor(SafeFreeNegoCredentials credential, String targetName)
at System.Net.Security.NegotiateStreamPal.EstablishSecurityContext(SafeFreeNegoCredentials credential, SafeDeleteContext& context, ChannelBinding channelBinding, String targetName, ContextFlagsPal inFlags, ReadOnlySpan`1 incomingBlob, Byte[]& resultBuffer, ContextFlagsPal& outFlags)
at System.Net.Security.NegotiateStreamPal.InitializeSecurityContext(SafeFreeCredentials& credentialsHandle, SafeDeleteContext& securityContext, String spn, ContextFlagsPal requestedContextFlags, ReadOnlySpan`1 incomingBlob, ChannelBinding channelBinding, Byte[]& resultBlob, Int32& resultBlobLength, ContextFlagsPal& contextFlags)
at System.Net.NTAuthentication.GetOutgoingBlob(ReadOnlySpan`1 incomingBlob, Boolean throwOnError, SecurityStatusPal& statusCode)
at System.Net.Security.NegotiateAuthentication.GetOutgoingBlob(ReadOnlySpan`1 incomingBlob, NegotiateAuthenticationStatusCode& statusCode)
at Data8.PowerPlatform.Dataverse.Client.ADAuthClient.Authenticate()
at Data8.PowerPlatform.Dataverse.Client.ADAuthClient.Execute(OrganizationRequest request)
at Data8.PowerPlatform.Dataverse.Client.OnPremiseClient.Execute(OrganizationRequest request)
at Ahanonline.Common.DynamicsClient.DynamicsClientService.SetStatus(SetStatusParam param) in /src/Common/DynamicsClient/DynamicsClientService.cs:line 112
at Ahanonline.Services.OnlineQuotes.OnlineQuotesService.UpdateStatus(UpdateOnlineQuoteStatusRequest body, Requester requester) in /src/Services/OnlineQuotes/OnlineQuotesService.cs:line 48
at Ahanonline.App.Controllers.OnlineQuotesController.UpdateStatus(UpdateOnlineQuoteStatusRequest dto, Requester requester) in /src/App/Controllers/OnlineQuotesController.cs:line 30
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskResultExecutor.Execute(ActionContext actionContext, 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.<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__Logged|17_1(ResourceInvoker invoker)
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 Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Ahanonline.Common.Exceptions.Middlewares.AppExceptionHandlerMiddleware.Invoke(HttpContext context) in /src/Common/Exceptions/Middlewares/AppExceptionHandlerMiddleware.cs:line 24
Anyone got any idea how to resolve this issue ?
I added an implementation on my github repository. The requirements is that you have an on-premise dynamics 365 to test it.
https://github.com/nimasfl/dotnet7-dynamics-test

Can't upload a file to Autodesk Forge OSS bucket

I have created an OSS bucket and I'm trying to upload a file to it, but getting an error every time. Here is my bucket:
{
"dictionary": {
"bucketKey": "-removed my client id-------------test1",
"bucketOwner": "-removed my client id------------",
"createdDate": 1661180310185,
"permissions": {
"dictionary": {
"0": {
"dictionary": {
"authId": "-removed my client id------------",
"access": "full"
},
"count": 2
}
},
"count": 1
},
"policyKey": "temporary"
},
"count": 5
}
When I try to upload a CAD file to the bucket, I get an error as shown below. I have created a few buckets with another app, and even gone so far as to remove my old app and create a new one. Same issue.
Autodesk.Forge.Client.ApiException: Error calling UploadObject: {"reason":"No write access"}
at Autodesk.Forge.ObjectsApi.UploadObjectAsyncWithHttpInfo(String bucketKey, String objectName, Nullable`1 contentLength, Stream body, String contentDisposition, String ifMatch, String contentType)
at Autodesk.Forge.ObjectsApi.UploadObjectAsync(String bucketKey, String objectName, Nullable`1 contentLength, Stream body, String contentDisposition, String ifMatch, String contentType)
at PE_AutodeskForgeService.Controllers.OSSController.UploadObject(UploadFile input) in D:\Code\PE_AutodeskForgeService\PE_AutodeskForgeService\Controllers\OSSController.cs:line 127
at lambda_method61(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.<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)
HEADERS
=======
Accept: */*
Connection: keep-alive
Host: localhost:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 Edg/104.0.1293.63
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryr5CxWcAi4docJmf4
Origin: http://localhost:3000
Referer: http://localhost:3000/swagger/index.html
Content-Length: 364166
sec-ch-ua: "Chromium";v="104", " Not A;Brand";v="99", "Microsoft Edge";v="104"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Pretty sure this isn't a Scope issue, as scope is set as shown below:
public static async Task<dynamic> GetInternalAsync()
{
if (InternalToken == null || InternalToken.ExpiresAt < DateTime.UtcNow)
{
InternalToken = await Get2LeggedTokenAsync(new Scope[] { Scope.BucketCreate, Scope.BucketRead, Scope.BucketUpdate, Scope.BucketDelete, Scope.DataRead, Scope.DataWrite, Scope.DataCreate, Scope.CodeAll });
InternalToken.ExpiresAt = DateTime.UtcNow.AddSeconds(InternalToken.expires_in);
}
return InternalToken;
}
Please check two things:
that your code is generating the token for the same Forge Client ID that owns the bucket
that your Forge subscription is valid (if it's a trial, perhaps it has expired?)
And if none of the above helps, please share your Forge Client ID and the name of one of the problematic buckets with us via forge (dot) help (at) autodesk (dot) com.

Getting SqlException and ObjectDisposedException in Asp.net core 5 webapi

I have a repository for albums table (album entity) and I do filtering and paging in repository as you see:
public IQueryable<Album> GetAllAlbums(AlbumQueryParameters queryParameters)
{
var albums = _cache.Get<IQueryable<Album>>("_AllAlbums");
if(albums == null){
albums = _context.Albums;
_cache.Set<IQueryable<Album>>("_AllAlbums", albums, ApplicationDefaults.MemoryCachingOption);
}
if(queryParameters.ArtistId != null)
{
albums = albums.Include(a => a.ArtistToAlbums)
.SelectMany(a => a.ArtistToAlbums)
.Where(a => a.ArtistId == Convert.ToInt32(queryParameters.ArtistId))
.Select(a => a.Album);
}
if(queryParameters.GenreId != null)
{
albums = albums.Include(a => a.AlbumToGenres)
.SelectMany(a => a.AlbumToGenres)
.Where(a => a.GenreId == Convert.ToInt32(queryParameters.GenreId))
.Select(a => a.Album);
}
// Pagination
albums = albums.Skip(queryParameters.Size * (queryParameters.Page - 1))
.Take(queryParameters.Size);
return albums;
}
And here is my controller:
[HttpGet]
public async Task<IActionResult> GetAllAlbums([FromQuery] AlbumQueryParameters queryParameters)
{
var albums = _albumRepository.GetAllAlbums(queryParameters);
return Ok(await albums.ToListAsync());
}
When I try to get data from this action I get this error:
Microsoft.Data.SqlClient.SqlException (0x80131904): The number of rows provided for a FETCH clause must be greater then zero.
at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at Microsoft.Data.SqlClient.SqlDataReader.TryHasMoreRows(Boolean& moreRows)
at Microsoft.Data.SqlClient.SqlDataReader.TryReadInternal(Boolean setTimeout, Boolean& more)
at Microsoft.Data.SqlClient.SqlDataReader.ReadAsyncExecute(Task task, Object state)
at Microsoft.Data.SqlClient.SqlDataReader.InvokeAsyncCall[T](AAsyncCallContext`1 context)
--- End of stack trace from previous location ---
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at StoreApi.Controllers.AlbumController.GetAllAlbums(AlbumQueryParameters queryParameters) in /home/nalien/Projects/albumshop/StoreApi/Controllers/AlbumController.cs:line 27
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>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__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)
ClientConnectionId:66426711-f9b4-470a-898d-a0a0bd3082d1
Error Number:10744,State:1,Class:15
HEADERS
=======
Connection: keep-alive
Accept: */*
Accept-Encoding: gzip, deflate, br
Host: localhost:5001
Referer: http://localhost:5000/api/album?artistId=1
User-Agent: PostmanRuntime/7.26.8
Postman-Token: 317f1fb0-a03b-4c15-a6da-87b69934bf57
And when I comment the Pagination I get a new error:
System.ObjectDisposedException: Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'ApplicationDbContext'.
at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.get_ChangeTracker()
at Microsoft.EntityFrameworkCore.Query.CompiledQueryCacheKeyGenerator.GenerateCacheKeyCore(Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.RelationalCompiledQueryCacheKeyGenerator.GenerateCacheKeyCore(Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.SqlServer.Query.Internal.SqlServerCompiledQueryCacheKeyGenerator.GenerateCacheKey(Expression query, Boolean async)
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.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
at StoreApi.Controllers.AlbumController.GetAllAlbums(AlbumQueryParameters queryParameters) in /home/nalien/Projects/albumshop/StoreApi/Controllers/AlbumController.cs:line 27
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)
HEADERS
=======
Connection: keep-alive
Accept: */*
Accept-Encoding: gzip, deflate, br
Host: localhost:5001
Referer: http://localhost:5000/api/album?artistId=2
User-Agent: PostmanRuntime/7.26.8
Postman-Token: 6291c9cf-87cd-45a8-bc84-8d796efbed03
And here is the way I registered my services:
services.AddDbContext<ApplicationDbContext>(options => {options.UseSqlServer(configuration.GetConnectionString("MainDatabase"));});
services.AddTransient<IAlbumRepository, AlbumRepository>();
services.AddMemoryCache();
I don't know what to do to fix my problem.
The first exception happened when Skip and Take is zero, so you can check it before add pagination to query:
if(queryParameters.Size>0)
albums = albums.Skip(queryParameters.Size * (queryParameters.Page - 1)) .Take(queryParameters.Size);
The second exception is about object life time you add ApplicationDbContext as Scope means it lives in request life time but you add IAlbumRepository as Transient means a new instance is provided to every call interface so when you call this line:
var albums = _albumRepository.GetAllAlbums(queryParameters);
One instance of IAlbumRepository created and when respond and return albums, it will disposed and any objects in it will disposed (includes ApplicationDbContext), for prevent this exception just add IAlbumRepository as Scoped like this:
services.AddScoped<IAlbumRepository, AlbumRepository>();
I think it's better to return List instead of IQueryable some thing like this:
public async List<Album> GetAllAlbums(AlbumQueryParameters queryParameters)
{
//do some stuff
return await ablums.ToListAsync();
}
And in the controller:
return Ok(await _albumRepository.GetAllAlbums(queryParameters));

How do I add a scoped DbContext to my ASP NET Core API Controllers that uses EntityFrameworkCore and SSH tunneling into MySQL?

I have the following ConfigureServices() content in my Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext<GMContext>(options =>
{
var myConnectionSettings = Configuration.GetSection("ConnectionSettings").Get<ConnectionSettings>();
var sshSettings = myConnectionSettings.SSH;
var databaseSettings = myConnectionSettings.Database;
string keyFilePath = Path.Combine(Directory.GetCurrentDirectory(), "test4");
var authMethods = new List<AuthenticationMethod>
{
new PrivateKeyAuthenticationMethod(sshSettings.UserName, new PrivateKeyFile(keyFilePath))
};
using (var sshClient = new SshClient(new ConnectionInfo(sshSettings.Server,
sshSettings.Port, sshSettings.UserName, authMethods.ToArray())))
{
sshClient.Connect();
var forwardedPort = new ForwardedPortLocal(databaseSettings.BoundHost, databaseSettings.Host,
databaseSettings.Port);
sshClient.AddForwardedPort(forwardedPort);
forwardedPort.Start();
MySqlConnectionStringBuilder csb;
csb = new MySqlConnectionStringBuilder
{
Server = databaseSettings.BoundHost,
Port = forwardedPort.BoundPort,
UserID = databaseSettings.UserName,
Password = databaseSettings.Password,
Database = databaseSettings.DatabaseName
};
options.UseMySQL(csb.ConnectionString);
}
});
I then pick up the context in a controller and attempt to query the context I get a connection denied error:
namespace CoreGMWebAPI.Controllers
{
[Produces("application/json")]
[Route("api/[controller]")]
public class CropController : Controller
{
private readonly ILogger<CropController> _logger;
private readonly GMContext _context;
public CropController(ILogger<CropController> logger, GMContext context)
{
_logger = logger;
_context = context;
}
/// <summary>
/// Gets a Sample Items
/// </summary>
/// <returns></returns>
[HttpGet]
public async Task<List<TCountries>> GetSampleItems()
{
var result = _context.TCountries.Take(10).ToList();
return result;
}
}
}
The Error:
System.InvalidOperationException: An exception has been raised that is
likely due to a transient failure. Consider enabling transient error
resiliency by adding 'EnableRetryOnFailure()' to the 'UseMySql' call.
---> MySql.Data.MySqlClient.MySqlException (0x80004005): Unable to connect to any of the specified MySQL hosts. --->
System.AggregateException: One or more errors occurred. (No connection
could be made because the target machine actively refused it.
127.0.31.1:54960) ---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException
(10061): No connection could be made because the target machine
actively refused it. 127.0.31.1:54960 at
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw(Exception
source) at System.Net.Sockets.Socket.EndConnect(IAsyncResult
asyncResult) at
System.Net.Sockets.TcpClient.EndConnect(IAsyncResult asyncResult)
at System.Net.Sockets.TcpClient.<>c.b__28_1(IAsyncResult
asyncResult) at
System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean
requiresSynchronization) --- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean
includeTaskCanceledExceptions) at
System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout,
CancellationToken cancellationToken) at
System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout) at
MySql.Data.Common.StreamCreator.GetTcpStream(MySqlConnectionStringBuilder
settings) at
MySql.Data.Common.StreamCreator.GetStream(MySqlConnectionStringBuilder
settings) at MySql.Data.MySqlClient.NativeDriver.Open() at
MySql.Data.MySqlClient.NativeDriver.Open() at
MySql.Data.MySqlClient.Driver.Open() at
MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder
settings) at
MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection() at
MySql.Data.MySqlClient.MySqlPool.GetPooledConnection() at
MySql.Data.MySqlClient.MySqlPool.TryToGetDriver() at
MySql.Data.MySqlClient.MySqlPool.GetConnection() at
MySql.Data.MySqlClient.MySqlConnection.Open() at
Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Boolean
errorsExpected) at
Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean
errorsExpected) at
Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject
parameterObject) at
Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable1.Enumerator.InitializeReader(DbContext _, Boolean result) at MySql.Data.EntityFrameworkCore.Storage.Internal.MySQLExecutionStrategy.Execute[TState,TResult](TState state, Func3 operation, Func3 verifySucceeded) --- End of inner exception stack trace --- at MySql.Data.EntityFrameworkCore.Storage.Internal.MySQLExecutionStrategy.Execute[TState,TResult](TState state, Func3 operation, Func3 verifySucceeded) at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable1.Enumerator.MoveNext()
at System.Collections.Generic.List1..ctor(IEnumerable1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at
CoreGMWebAPI.Controllers.CropController.GetSampleItem() in
C:\Users\lobos\source\repos\CoreGMWebAPI\CoreGMWebAPI\Controllers\CropController.cs:line
31 at lambda_method(Closure , Object ) at
Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
at
Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper
mapper, ObjectMethodExecutor executor, Object controller, Object[]
arguments) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Logged|12_1(ControllerActionInvoker
invoker) at
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.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 where exception was thrown --- at
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker
invoker, Task lastTask, State next, Scope scope, Object state, Boolean
isCompleted) at
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged|17_1(ResourceInvoker
invoker) at
Microsoft.AspNetCore.Routing.EndpointMiddleware.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)
HEADERS
======= Accept: application/json Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9,ca;q=0.8,fr;q=0.7,nb;q=0.6 Connection:
close Host: localhost:44313 Referer:
https://localhost:44313/swagger/index.html User-Agent: Mozilla/5.0
(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/86.0.4240.198 Safari/537.36 dnt: 1 sec-fetch-site: same-origin
sec-fetch-mode: cors sec-fetch-dest: empty sec-gpc: 1
When I run the following quick test inside the ConfigureServices() method in Startup.cs it connects and queries without any issues:
...
options.UseMySQL(csb.ConnectionString);
var otherOps = new DbContextOptionsBuilder<GMContext>();
otherOps.UseMySQL(csb.ConnectionString);
using (var context = new GMContext(otherOps.Options))
{
var testRun = context.TCountries.Take(3).ToList();
}
This leads me to suspect that the SSHClient is closing before the Controller can use the dbContext. Should I somehow be passing the SSHClient as well as the dbContext? Any help would be appreciated.

Categories