2017-09-18 6 views
0

J'ai un site Web qui prend en charge les messages envoyés aux utilisateurs (un courriel est envoyé à tout le monde, ils cliquent sur un lien qui appelle une action du contrôleur). Je veux utiliser un webjob pour envoyer les emails, mais j'ai besoin de parcourir tous les utilisateurs de la base de données pour récupérer les adresses e-mail.Configurer un dbContext à partir d'un travail Web

J'ai mis en place le site Web et tout fonctionne très bien. Je l'DbContext héritant de IdentityDbContext ici:

public class MooodDbContext : IdentityDbContext<ApplicationUser> 
    { 
     public MooodDbContext(DbContextOptions options) : base(options) 
     { 

     } 

     public DbSet<Response> Response { get; set; } 

     public DbSet<Cow> Cow { get; set; } 

     public DbSet<Herd> Herd { get; set; } 
    } 

Les ConfigureServices est exécuté lorsque je lance le webapp

public void ConfigureServices(IServiceCollection services) 
     { 
      // Add framework services. 
      services.AddDbContext<MooodDbContext>(options => 
       options.UseSqlServer(Configuration.GetConnectionString("MooodConnection"))); 

      services.AddIdentity<ApplicationUser, IdentityRole>() 
       .AddEntityFrameworkStores<MooodDbContext>() 
       .AddDefaultTokenProviders(); 

      services.AddMvc(options => options.Filters.Add(typeof(UnauthorizedExceptionFilterAttribute))); 

      services.AddScoped<IDbInitializer, DbInitializer>(); 

      // Add application services. 
      services.AddTransient<IEmailSender, AuthMessageSender>(); 
      services.AddTransient<ISmsSender, AuthMessageSender>(); 

     } 

mais évidemment pas quand je lance le webjob. Alors, quand je tente d'accéder à quoi que ce soit dans le contexte, je reçois cette exception (après la mise en contexte = nouveau contexte()):

System.InvalidOperationException occurred 
    HResult=0x80131509 
    Message=No database provider has been configured for this DbContext. A provider can be configured by overriding the DbContext.OnConfiguring method or by using AddDbContext on the application service provider. If AddDbContext is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext. 
    Source=Microsoft.EntityFrameworkCore 

Il me semble, c'est parce que je ne fais aucune configuration sur la DbContext, mais je ne suis pas sûr. Y a-t-il une meilleure façon d'accomplir cela? Ou est-ce que je manque quelque chose de petit?

Edit: Voici les Program.cs de mon webjob (moins la fonctionnalité courriel, qui est cluttery):

private static MooodDbContext _context; 

     // Please set the following connection strings in app.config for this WebJob to run: 
     // AzureWebJobsDashboard and AzureWebJobsStorage 

     private static void Main() 
     { 
      _context = new MooodDbContext(new DbContextOptions<MooodDbContext>()); 

      var host = new JobHost(); 

      EmailAllHerds(); 

      host.RunAndBlock(); 

      EmailAllHerds(); 
     } 
+0

Pourriez-vous aussi comment le webjob est exécuté? Sur une autre note, vous pourriez [vous simplifier la vie en utilisant SendGrid] (https://docs.microsoft.com/fr-fr/azure/app-service-web/sendgrid-dotnet-how-to-send-email –

+0

Est-ce une application de console construite sur «asp.net core»? Si oui, je peux poster du code qui pourrait aider – Jaya

+0

En fait, j'utilise SendGrid! Je n'ai juste pas montré le peu sur l'envoi de l'email pour éviter l'encombrement. A part ça, j'ai ajouté les parties program.cs. – jemtan990

Répondre

2

Couple d'hypothèses que je l'ai fait ici

  • emploi web est une console App construite sur le noyau .net

vous aurez fichier Program.cs avec une méthode principale . Donc, dans votre

Program.cs

class Program { 
    // declare a field to store config values 
    private readonly IConfigurationRoot _configuration; 
    // Declare a constructor 
    public Program() 
    { 
     var builder = new ConfigurationBuilder() 
      .SetBasePath(environment.BasePath) 
      .AddJsonFile($"appsettings.json", true, true) 
      .AddJsonFile($"appsettings.{environment.EnvironmentName}.json", true, true) 
      .AddEnvironmentVariables(); 

     _configuration = builder.Build(); 
    } 
} 
    public static void Main(string[] args) 
    { 
    var program = new Program(); 
    var serviceCollection = new ServiceCollection(); 
    program.ConfigureServices(serviceCollection);   

    } 

    private void ConfigureServices(IServiceCollection services) 
    { 
     // now here you can resolve your DbContext similar to web 
     services.AddDbContext<MooodDbContext>(options =>options.UseSqlServer(_configuration.GetConnectionString("MooodConnection"))); 
    } 
} 
+0

Mon fichier Program.cs n'a pas de constructeur (je l'ai juste ajouté comme modification), donc c'est peut-être ce qui me manque? Je ne suis pas sûr de toutes les configurations que vous avez, mais aucune d'entre elles ne semble liée à la base de données. Laissez-moi essayer d'ajouter le bit de collection Service dans ma main et voir si cela fonctionne. – jemtan990

+0

vous devez en créer un, c'est tout le point de ce code ^^, vous manquez la résolution DI sur Program.cs, vous ne pouvez pas attendre votre 'Startup.cs' sur le web pour être appelé sur votre webjob. Donc, vous devez avoir le code qui résout dans votre console App comme il s'agit d'une DLL individuelle et non connecté avec le web – Jaya

+0

Je vois votre point de vue maintenant que je l'ai regardé un peu plus près. Une question cependant - si cela ne vous dérange pas - il ne semble pas que ConfigurationBuilder ait l'une des méthodes que vous avez écrites? Ce n'est pas la classe que vous utilisez? https://docs.microsoft.com/en-us/aspnet/core/api/microsoft.extensions.configuration.configurationbuilder – jemtan990