Home > Back-end >  How to properly connect Dockerized SQL DB to .Net API
How to properly connect Dockerized SQL DB to .Net API

Time:08-11

I am trying to access my SQL Database through my API, all of which have already been dockerized and are able to run simultaneously, however, I can't seem to be able to access the database. The error is most likely in my connection string since that is how I connect to the SQL DB to get table info. Please keep in mind I am fairly new at this and I have tried multiple methods before asking here! Thank you and here is all the information I could gather.

appsettings.json:

{
  "ConnectionStrings": {
    "CollegeDBCon": "Server=mssql;Database=CollegeDB;User=sa;Password=SApassword123"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Docker-compose:

version: "3.9"
services:
  frontend:
    image: react-app
    restart: unless-stopped
    build:
      context: my-app
      target: base
      dockerfile: dockerfile
    ports:
      - 3000:3000
    networks:
      - shared-network

  api:
    image: webapi
    restart: always
    ports:
      - 5000:5000
    networks:
      - shared-network
    depends_on:
      - mssql

  mssql:
    image: mcr.microsoft.com/mssql/server:2019-latest
    environment:
      SA_PASSWORD: SApassword123
      ACCEPT_EULA: "Y"
    ports:
      - 1433:1433
    networks:
      - shared-network
    volumes:
      - CollegeDB:/data/db

networks:
  shared-network:

volumes:
  CollegeDB:

Error:

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      System.Data.SqlClient.SqlException (0x80131904): A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
       ---> System.ComponentModel.Win32Exception (53): The network path was not found.
         at System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, Boolean applyTransientFaultHandling, String accessToken)
         at System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
         at System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool pool, DbConnection owningObject, DbConnectionOptions options, DbConnectionPoolKey poolKey, DbConnectionOptions userOptions)
         at System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
         at System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject, DbConnectionOptions userOptions, DbConnectionInternal oldConnection)
         at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
         at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection)
         at System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
         at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
         at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
         at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
         at System.Data.SqlClient.SqlConnection.Open()
         at WebAPI.Controllers.StudentController.Get() in C:\Users\Jonathan\Downloads\College_DB\webapi\webapi\Controllers\StudentController.cs:line 36
         at lambda_method3(Closure , Object , Object[] )
         at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
      --- End of stack trace from previous location ---
         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 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:00000000-0000-0000-0000-000000000000
      Error Number:53,State:0,Class:20

If I change the connection string to: (How I access the DB on SMSS)

"CollegeDBCon": "Server=localhost,1443;Database=CollegeDB;User=sa;Password=SApassword123"

EDIT: ^ This used to give me an error but was fixed once I turned off my firewall. Now it works locally when testing, however, does not work when both the API and SQL are run through docker. Instead I get "Socket Hang Up" when testing the API through Postman.

CodePudding user response:

The following code fixed the errors I was getting, if you get any errors regarding "refused connection" then simply disable firewall.

"CollegeDBCon": "Server=host.docker.internal,1433;Database=CollegeDB;User=sa;Password=SApassword123"

CodePudding user response:

You got some networking issues between container:

Try to remove network part for 3 services in 3 containers.

    networks:
      - shared-network
   

Define a link parameter from api container and try again.

"CollegeDBCon": "Server=mssql,1433;Database=CollegeDB;User=sa;Password=SApassword123"

Add 1433 into connection string.

  • Related