服务中的 Blazor DbContext

问题描述 投票:0回答:1

我正在尝试从服务内部而不是从组件进行数据库插入,无论我做什么,都会给我带来空对象错误。我也用

DbContext
尝试过,并且遇到了同样的问题。我假设这与
DbContextFactory
服务中的依赖注入有关。
为我的服务尝试了

ConsoleWebhookReceiver

DbContext
,以及不同的启动配置以及带和不带存储库的情况。我是 Blazor 新手,还不太了解所有内容。我想知道您是否只能在服务器端进行实体框架依赖注入,以及我是否应该创建一个 API 控制器来处理这个问题,但在这个 webhook 接收器中执行数据库插入似乎是一件简单的事情,我肯定只是缺少一些简单的东西。

DbContextFactory

Program.cs

using BlazorApp.Services;
using BotTrading.Controllers;
using BotTrading.Data;
using BotTrading.Services;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();

builder.Services.AddScoped<IReceiveWebhook, ConsoleWebhookReceiver>();
builder.Services.AddScoped<IWebhookService, WebhookService>();
builder.Services.AddScoped<WebhookService>();
builder.Services.AddControllers();

builder.Services.AddDbContextFactory<AppDBContext>(options => 
    options
        .EnableSensitiveDataLogging()
        .UseSqlite(builder.Configuration.GetConnectionString("Database")));

var app = builder.Build();


var webhookService = app.Services.GetRequiredService<WebhookService>();
// var cryptoService = app.Services.GetRequiredService<CryptoService>();

// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();
app.MapControllers();
// app.UseMvc();

app.UseRouting();

app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

//Listen for POST webhooks
app.MapPost("/webhooks", async (HttpContext context, IReceiveWebhook receiveWebook) =>
{
    using StreamReader stream = new StreamReader(context.Request.Body);
    return await receiveWebook.ProcessRequest(await stream.ReadToEndAsync());
});

app.Run();

ConsoleWebhookReceiver.cs

public class ConsoleWebhookReceiver : IReceiveWebhook
{
    private readonly AppDBContext _appDbContext;
    private readonly IDbContextFactory<AppDBContext> _contextFactory;

    /// <summary>
    /// Writes the POST request body to the console and returns JSON and then inserts into database
    /// </summary>
    public async Task<string> ProcessRequest(string requestBody)
    {
        var context = await _contextFactory.CreateDbContextAsync();
        WebhookService webhookService = new WebhookService(context);
        
        // This is where you would put your actual business logic for receiving webhooks
        Console.WriteLine($"Request Body: {requestBody}");
        Webhook item = JsonConvert.DeserializeObject<Webhook>(requestBody);

        // These two calls to WebhookReceiver is where I am getting 
        // the null object reference. The item is passed into my 
        // webhookService, the item is not null, but in the service 
        // there is no context
        webhookService.CreateWebhook(item);
        Webhook webhook = webhookService.GetWebhookById(1).Result;

        return "{\"message\" : \"Thanks! We got your webhook\"}";
    }
}

IReceiveWebhook.cs

namespace BlazorApp.Services
{
    public interface IReceiveWebhook
    {
        Task<string> ProcessRequest(string requestBody);
    }
}

WebhookService.cs

using System;
using System.Threading.Tasks;
using BotTrading.Data;
using BotTrading.Services;
using Flurl.Util;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using NgrokApi;

namespace BlazorApp.Services
{
    public class WebhookService : IWebhookService
    {
        private readonly IDbContextFactory<AppDBContext> _contextFactory;
        private readonly AppDBContext _context;

        // public WebhookService(IDbContextFactory<AppDBContext> contextFactory)
        // {
        //     _contextFactory = contextFactory;
        // }
        public WebhookService(AppDBContext context)
        {
            _context = context;
        }

        public async Task<List<Webhook>> GetWebhookList()
        {
            using (var context = await _contextFactory.CreateDbContextAsync())
            {
                return await context.Webhooks
                    .ToListAsync();
            }
        }

        public async Task<Webhook> GetWebhookById(int id)
        {
            using (var context = await _contextFactory.CreateDbContextAsync())
            {
                return await context.Webhooks
                    .FirstOrDefaultAsync(x => x.Id == id);
            }
        }
  
        public async Task<Webhook> CreateWebhook(Webhook webhook)
        {
            using (var context = await _contextFactory.CreateDbContextAsync())
            {
                Console.WriteLine("webhook: " + webhook.Base);
                context.Webhooks.AddAsync(webhook);
                await context.SaveChangesAsync();
                return webhook;
            }
        }
        
        public async Task UpdateWebhook(Webhook player)
        {
            using (var context = _contextFactory.CreateDbContext())
            {
                context.Webhooks.Update(player);
                await context.SaveChangesAsync();
            }
        }
  
        public async Task DeleteWebhook(Webhook player)
        {
            using (var context = _contextFactory.CreateDbContext())
            {
                context.Webhooks.Remove(player);
                await context.SaveChangesAsync();
            }
        }
    }
}

IWebhookService.cs

AppDBContext.cs

using BotTrading.Data; namespace BotTrading.Services; public interface IWebhookService { Task<List<Webhook>> GetWebhookList(); Task<Webhook> GetWebhookById(int id); Task<Webhook> CreateWebhook(Webhook webhook); Task UpdateWebhook(Webhook webhook); Task DeleteWebhook(Webhook webhook); }

这是例外情况

失败:Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]

执行请求时发生未处理的异常。

System.NullReferenceException:未将对象引用设置为对象的实例。

在 BotTrading.Controllers.ConsoleWebhookReceiver.ProcessRequest(字符串 requestBody)

在程序中。<>c.

b__0_2>d.MoveNext()
--- 先前位置的堆栈跟踪结束 ---<<$> 在 Microsoft.AspNetCore.Http.RequestDelegateFactory.g__ExecuteAwaited|134_0(任务`1 任务,HttpContext httpContext)
在 Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext 上下文)
在 Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext 上下文)
在 Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext 上下文)

c# asp.net-core blazor dbcontext .net-8.0
1个回答
0
投票

它只是缺少一个

using Microsoft.EntityFrameworkCore; namespace BotTrading.Data; public class AppDBContext : DbContext { protected readonly IConfiguration Configuration; public AppDBContext(DbContextOptions<AppDBContext> options) : base(options) { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder .EnableSensitiveDataLogging() .EnableDetailedErrors() .LogTo(Console.WriteLine, new[] { DbLoggerCategory.Infrastructure.Name }) .UseSqlite(Configuration.GetConnectionString("Database")); } public DbSet<Crypto> Cryptos { get; set; } public DbSet<Trade> Trades { get; set; } public DbSet<Webhook> Webhooks { get; set; } }

然后它也应该被注入或解析到某个地方。

© www.soinside.com 2019 - 2024. All rights reserved.