41 messaggi dal 12 settembre 2010
Buongiorno,
sto provando a connettere l'applicazione ASP.NET Core MVC che sto realizzando ad un DB MySql.

Di seguito la configurazione del file "appsettings.json":
{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ConnectionString": {
    "DefaultConnection": "server=localhost;port=3306;database=aspnetcoremvc;user=root;password=xxxxxxxx"
  }
}


Di seguito la configurazione del file "Startup.cs":
public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
                  .SetBasePath(env.ContentRootPath)
                  .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                  .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                  .AddEnvironmentVariables();

    Configuration = builder.Build();
}

public IConfiguration Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    services.Add(new ServiceDescriptor(typeof(MusicStoreContext), new MusicStoreContext(Configuration.GetConnectionString("DefaultConnection"))));
}


Di seguito la configurazione del file "MusicStoreContext.cs" (posizionato nella root del progetto):
public string ConnectionString { get; set; }

public MusicStoreContext(string connectionString)
{
   this.ConnectionString = connectionString;
}

private MySqlConnection GetConnection()
{
   return new MySqlConnection(ConnectionString);
}
public List<Album> GetAllAlbums()
{
    List<Album> list = new List<Album>();

    using (MySqlConnection conn = GetConnection())
    {
        conn.Open();
        MySqlCommand cmd = new MySqlCommand("select * from Album where id < 10", conn);

        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                list.Add(new Album()
                {
                    Id = Convert.ToInt32(reader["Id"]),
                    Name = reader["Name"].ToString(),
                    ArtistName = reader["ArtistName"].ToString(),
                    Price = Convert.ToInt32(reader["Price"]),
                    Genre = reader["genre"].ToString()
                });
            }
        }
    }
    return list;
}


Questo il controller che fa il richiamo della view (che poi mi genera errore):
[Area("Admin")]
public class AdminController : Controller
{
    public IActionResult Index()
    {
        MusicStoreContext context = HttpContext.RequestServices.GetService(typeof(AspNetCoreMVCCMS.MusicStoreContext)) as MusicStoreContext;

        return View(context.GetAllAlbums());
    }
}


Questo è l'errore che mi viene segnalato dalla view:
MySql.Data.MySqlClient.MySqlException (0x80004005): Host '192.168.1.180' is not allowed to connect to this MariaDB server
   at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
   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 AspNetCoreMVCCMS.MusicStoreContext.GetAllAlbums() in C:\Users\Alessio\Dropbox\VS2017\AspNetCoreMVC-CMS\AspNetCoreMVC-CMS\MusicStoreContext.cs:line 30
   at AspNetCoreMVCCMS.Areas.Admin.Controllers.AdminController.Index() in C:\Users\Alessio\Dropbox\VS2017\AspNetCoreMVC-CMS\AspNetCoreMVC-CMS\Areas\Admin\Controllers\AdminController.cs:line 17
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
   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.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)


Ho notato che quando viene richiamato questo metodo del file "MusicStoreContext.cs" (durante l'esecuzione di ConfigureServices di Startup.cs):
public MusicStoreContext(string connectionString)
{
    this.ConnectionString = connectionString;
}

il valore di "connectionString" è nullo.

Spero che qualcuno possa aiutarmi e vi ringrazio in anticipo.

Saluti,
Alessio.
10.957 messaggi dal 09 febbraio 2002
Contributi
Ciao Alesso,


Di seguito la configurazione del file "Startup.cs":

Il costruttore puoi anche non metterlo, infatti mi sembra che tu stia ricostruendo le fonti di configurazione così come quelle di default, quindi puoi anche togliere quel codice.
Di conseguenza puoi anche togliere la proprietà Configuration.

Nel metodo ConfigureServices sostituisci questa riga:
 services.Add(new ServiceDescriptor(typeof(MusicStoreContext), new MusicStoreContext(Configuration.GetConnectionString("DefaultConnection"))));


Con questa, che è molto pi semplice e concisa.
services.AddScoped<MusicStoreContext>();


Poi, passando al MusicStoreContext, modifica il suo costruttore così. In pratica, sfrutti la dependency injection di ASP.NET Core per farti passare l'istanza dell'oggetto che implementa IConfiguration.Il resto rimane invariato.
public MusicStoreContext(IConfiguration configuration)
{
   this.ConnectionString = configuration.GetConnectionString("DefaultConnection");
}


Poi, questo codice che si trova nel controller può essere semplificato, quindi eliminalo. Si tratta del service locator ed è un antipattern.
MusicStoreContext context = HttpContext.RequestServices.GetService(typeof(AspNetCoreMVCCMS.MusicStoreContext)) as MusicStoreContext;


Sfrutta invece il meccanismo di depedency injection prendendo il MusicStoreContext come parametro del costruttore oppure come parametro dell'action. Se lo ricevi come parametro dell'action, lo devi decorare con l'attributo [FromServices]
[Area("Admin")]
public class AdminController : Controller
{
    public IActionResult Index([FromServices] MusicStoreContext context)
    {
        return View(context.GetAllAlbums());
    }
}



Alcuni consigli:
  • Usa i metodi asincroni: OpenAsync al posto di Open; ExecuteAsync al posto di Execute; ReadAsync al posto di Read. Questo vuol dire che il tuo metodo GetAllAlbums dovrà diventare asincrono e così pure l'action Index. Async all the way!
  • Dovresti far implementare un'interfaccia al tuo MusicStoreContext e avere una dipendenza da quella nel controller, anziché dall'implmentazione concreta. In questo modo il tuo codice è più testabile. Program to an interface, not an implementation.
  • La proprietà Price è un int. Supponiamo che valga 10 ma... 10 cosa? Pigne? Price dovrebbe sempre essere un tipo complesso che contiene le proprietà Currency (string o enum) e Amount (decimal). Le due informazioni sono contemporaneamente necessarie. E' un value object.


Per il resto ok!

Ciao,
Moreno
Modificato da BrightSoul il 27 settembre 2018 20.47 -

Enjoy learning and just keep making
41 messaggi dal 12 settembre 2010
Buongiorno Moreno,
intanto grazie per avermi risposto e ho fatto le modifiche come mi hai indicato.

Ora il mio file Startup.cs è configurato nel modo seguente:
public class Startup
    {
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });


            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.AddScoped<MusicStoreContext>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "area",
                    template: "{area:exists}/{controller=Admin}/{action=Index}/{id?}");

                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }


Il file MusicStoreContext.cs è configurato così:
public class MusicStoreContext
    {
        public string ConnectionString { get; set; }

        public MusicStoreContext(IConfiguration configuration)
        {
            this.ConnectionString = configuration.GetConnectionString("DefaultConnection");
        }

        private MySqlConnection GetConnection()
        {
            return new MySqlConnection(ConnectionString);
        }

        public List<Album> GetAllAlbums()
        {
            List<Album> list = new List<Album>();

            using (MySqlConnection conn = GetConnection())
            {
                conn.Open();
                MySqlCommand cmd = new MySqlCommand("select * from Album where id < 10", conn);

                using (var reader = cmd.ExecuteReader())
                {
                    while (reader.Read())
                    {
                        list.Add(new Album()
                        {
                            Id = Convert.ToInt32(reader["Id"]),
                            Name = reader["Name"].ToString(),
                            ArtistName = reader["ArtistName"].ToString(),
                            Price = Convert.ToInt32(reader["Price"]),
                            Genre = reader["genre"].ToString()
                        });
                    }
                }
            }
            return list;
        }
    }


Ed il controller nel modo seguente:
[Area("Admin")]
    public class AdminController : Controller
    {
        public IActionResult Index([FromServices] MusicStoreContext context)
        {
            return View(context.GetAllAlbums());
        }
    }


Comunque ricevo sempre questo errore:
MySql.Data.MySqlClient.MySqlException (0x80004005): Host 'DESKTOP-0BV0STS.homenet.telecomitalia.it' is not allowed to connect to this MariaDB server
   at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
   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 AspNetCoreMVCCMS.MusicStoreContext.GetAllAlbums() in C:\Users\Alessio\Dropbox\VS2017\AspNetCoreMVC-CMS\AspNetCoreMVC-CMS\MusicStoreContext.cs:line 31
   at AspNetCoreMVCCMS.Areas.Admin.Controllers.AdminController.Index(MusicStoreContext context) in C:\Users\Alessio\Dropbox\VS2017\AspNetCoreMVC-CMS\AspNetCoreMVC-CMS\Areas\Admin\Controllers\AdminController.cs:line 15
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
   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.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)


Può dipendere dal fatto che quando avvio xampp è in ascolto sulla porta 8080? Infatti per accedere a phpmyadmin devo digitare localhost:8080/phpmyadmin.

Grazie,
Alessio.
10.957 messaggi dal 09 febbraio 2002
Contributi
Ciao Alessio,

Può dipendere dal fatto che quando avvio xampp è in ascolto sulla porta 8080?

No, xampp in questo caso non c'entra. La tua applicazione si collega direttamente alla porta 3306 di MariaDb e la connessione viene rifiutata con questo errore.

'DESKTOP-0BV0STS.homenet.telecomitalia.it' is not allowed to connect to this MariaDB server


Sembra che l'utente con il quale ti stai collegando non sia abilitato ad accedere da quel nome host. Sei sicuro che stai usando una connection string in cui hai server=localhost?
Per prima cosa verifichiamo che la connection string stia arrivando correttamente al MusicStoreContext e perciò metti in un breakpoint all'interno del metodo GetConnection e verifica che ConnectionString contenga il giusto valore.

Se la connection string è ok ma comunque non riesci ad accedere, devi controllare in MariaDb come sono messi i privilegi per l'utente che stai cercando di usare.

Fai questa query sul tuo database MySQL per verificare quali utenti sono attivi e da quale host possono collegarsi:
SELECT * FROM mysql.user;


Se ti accorgi che l'utente che stai usando non c'è o non può collegarsi dall'host da cui arrivi tu, allora dovrai usare i comandi GRANT per conferirgli i giusti privilegi di accesso.
https://www.mrwebmaster.it/mysql/gestire-utenti-permessi-grant-revoke_7041.html


ciao,
Moreno

Enjoy learning and just keep making
41 messaggi dal 12 settembre 2010
Ciao Moreno,
ancora grazie intanto e soprattutto :)

Credo di aver risolto creando un nuovo utente su MySql al quale ho assegnato tutti i privilegi e ho abilitato tutti gli host.

Ora però ho questo problema:
MySql.Data.MySqlClient.MySqlException (0x80004005): The host  does not support SSL connections.
   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 AspNetCoreMVCCMS.MusicStoreContext.GetAllAlbums() in C:\Users\Alessio\Dropbox\VS2017\AspNetCoreMVC-CMS\AspNetCoreMVC-CMS\MusicStoreContext.cs:line 31
   at AspNetCoreMVCCMS.Areas.Admin.Controllers.AdminController.Index(MusicStoreContext context) in C:\Users\Alessio\Dropbox\VS2017\AspNetCoreMVC-CMS\AspNetCoreMVC-CMS\Areas\Admin\Controllers\AdminController.cs:line 15
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
   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.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)


Ho provato a configurare il file appsettings.json nel modo seguente ma continuo ad avere lo stesso errore:
{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ConnectionString": {
    "DefaultConnection": "server=localhost;port=3306;database=aspnetcoremvc;user=alessio;password=xxxxxxxx;SslMode=none"
  }
}


Grazie,
Alessio.
Modificato da Gargano10041983 il 28 settembre 2018 08.55 -
41 messaggi dal 12 settembre 2010
Ciao Moreno,
ho fatto diversi tentativi ma purtroppo ottengo sempre l&#8217;ultimo errore che ti ho segnalato.

Andando in debug in questo punto:
public MusicStoreContext(IConfiguration configuration)
        {
            this.ConnectionString = configuration.GetConnectionString("DefaultConnection");
        }


continuo a notare che ConnectionString è sempre null.

Grazie,
Alessio.
10.957 messaggi dal 09 febbraio 2002
Contributi
Scusa, mi sono accorto adesso di un problema nel file appsettings.json.
Il nome da usare non è "ConnectionString" ma "ConnectionStrings". Nota la "s" finale in questo esempio:
{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ConnectionStrings": {
    "DefaultConnection": "server=localhost;port=3306;database=aspnetcoremvc;user=root;password=xxxxxxxx;SslMode=none"
  }
}


Così dovrebbe andare. E' corretto usare SSLMode=None, almeno finché sei in sviluppo.
ciao,
Moreno
Modificato da BrightSoul il 29 settembre 2018 21.08 -

Enjoy learning and just keep making
41 messaggi dal 12 settembre 2010
Grazie mille Moreno!!!
Proprio non avevo notato quell'errore di scrittura nel file appsettings.json

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.