小编Láz*_*olt的帖子

如何在 ASP.NET Core 5 运行时动态重新配置服务?

我在我的网络应用程序中使用 Google 身份验证,并且 OAuth 密钥当前硬编码在ConfigureServices 中:

services.AddAuthentication()
    .AddGoogle(options =>
    {
        options.ClientId = "my-client-id";
        options.ClientSecret = "my-client-secret";
    });
Run Code Online (Sandbox Code Playgroud)

但是,我想让站点管理员有机会从 Web 应用程序的设置页面更改 ClientId 和 ClientSecret,最好无需重新启动服务器。

为此,当用户在设置页面上点击“保存”时,我必须以某种方式触发 Google 服务和 GoogleOptions 对象的重新配置。这就是我遇到的麻烦。另外,我想将这些设置存储在 EF Core DbContext 中,而不是存储在物理配置文件中。

到目前为止,我已尝试将设置移动到实现 IPostConfigureOptions 的单独类中。这应该允许我注入我的数据库上下文,因为根据文档,PostConfigure 应该在所有其他配置发生后运行。设置已从这个新类正确加载,但数据库上下文的注入失败,并出现以下异常:

System.InvalidOperationException: Cannot consume scoped service 'AppDatabase' from singleton 'IOptionsMonitor`1[GoogleOptions]'
Run Code Online (Sandbox Code Playgroud)

这很奇怪,因为ConfigureGoogleOptions 注册为Scoped,而不是Singleton。

这是我的选项类:

public class ConfigureGoogleOptions : IPostConfigureOptions<GoogleOptions>
{
    private readonly AppDatabase database;

    public ConfigureGoogleOptions(AppDatabase database)
    {
        this.database = database;
    }
    
    public void PostConfigure(string name, GoogleOptions options)
    {
        options.ClientId = "my-client-id.apps.googleusercontent.com";
        options.ClientSecret = "my-client-secret";
    } …
Run Code Online (Sandbox Code Playgroud)

c# entity-framework dependency-injection asp.net-core

6
推荐指数
1
解决办法
3613
查看次数

如何获取 Blazor 服务器组件中的当前电路 ID?

我正在尝试向我的应用程序添加更详细的错误日志记录,以便在电路崩溃时记录当前页面 url。执行此操作的一种方法是重写OnCircuitClosedAsynccustom 中的方法CircuitHandler,但是我不知道如何将电路 id 字符串与活动用户会话关联起来。

我知道我可以通过注入来跟踪 CircuitHandler 中的用户IHttpContextAccessor(请参阅答案),但是用户可以打开多个选项卡,甚至可以有多个并发登录会话,并且我需要确切地知道为每个会话分配了哪个电路 ID单独的页面组件。

有没有办法从 Blazor 组件获取当前电路 ID,即使同一用户打开了多个选项卡(即与其帐户关联的多个电路)?

c# blazor blazor-server-side

6
推荐指数
1
解决办法
856
查看次数

TDLib:下载文件而不保存到磁盘

我正在使用TDLib在 C# 中实现我的自定义 Telegram 客户端。初始化库时,我必须设置电报缓存文件和本地数据库的文件夹。每当我使用 下载照片时TdApi.DownloadFile,它都会保存在该文件夹中,大概是为了缓存。

是否可以禁用此功能,并且仅在内存中接收文件,作为 aStream或 a byte[]

我了解缓存的好处,但出于我的应用程序特定的安全(和存储空间)原因,我想完全避免文件系统中的任何缓存。我愿意牺牲性能和加载速度。

我能想到两种可能的解决方案。我可以编写在应用程序关闭和启动时自动清除下载缓存文件夹的代码,或者我可以以某种方式实现官方桌面客户端的功能,并以加密格式存储缓存文件。第一个解决方案在安全性方面不是很好,我不知道如何实现第二个解决方案。所以最好禁用缓存。

这可能吗?如果可能的话,如何实现?

c# caching telegram tdlib

5
推荐指数
0
解决办法
1352
查看次数

EF Core 5 - 如何将 EF.Functions.Like 与映射到 JSON 字符串的自定义属性一起使用?

在我的一个数据库模型中,我有一个具有自定义类型 ( Dictionary<string, string>) 的属性,它会使用自定义转换器自动与 JSON 相互转换,并作为text字段存储在数据库中。我希望能够使用 MySQL 的LIKE比较器来搜索此 JSON 字段中的字符串,但出现异常。我不关心 JSON 的结构,我可以将其视为简单的文本字段并以这种方式进行搜索。

这是我尝试执行的方法(Sku是复杂类型):

var responseSet = database.Products.Where(p => EF.Functions.Like(p.Sku, "%query%"));
Run Code Online (Sandbox Code Playgroud)

这是我得到的例外:

An unhandled exception has occurred while executing the request.
System.InvalidOperationException: The LINQ expression 'DbSet<ProductObject>()
    .Where(p => __Functions_0
        .Like(
            matchExpression: p.Sku, pattern: __Format_1))' could not be translated. 
            Additional information: 
              Translation of method 'Microsoft.EntityFrameworkCore.MySqlDbFunctionsExtensions.Like' 
              failed. If this method can be mapped to your custom function, 
              see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. 
Run Code Online (Sandbox Code Playgroud)

异常中的链接指向一个带有大量交叉引用的长 git 问题,但我无法在其中找到任何有用的内容。 …

c# mysql entity-framework entity-framework-core asp.net-core

5
推荐指数
1
解决办法
2133
查看次数

有没有办法强制卸载 AssemblyLoadContext?

我正在开发一个大型 ASP.Net 5 Web 应用程序,我想实现自我更新功能。由于程序可以以不同的方式部署在许多不同的平台上(例如Windows服务,Linux上的systemd服务,Docker容器等......),实现自我更新机制的唯一可行的方法是编写一个主机进程可以加载和卸载主程序DLL及其依赖项。卸载很重要,因为主机程序(更新程序)必须能够在运行时覆盖服务器的 DLL 文件。

以下是我到目前为止所做的工作:我已将主 Web 应用程序的输出类型更改为 Library,并且制作了一个小型加载程序,该程序将该 DLL 及其依赖项加载到 中HostAssemblyLoadContext,然后调用原始Main()方法。服务器应用程序被编程为在启动后几秒钟正常关闭,因此该CreateHostBuilder(args).Build().Run()方法Main()可以返回。之后,我尝试调用HostAssemblyLoadContext.Unload(),但由于某种原因,加载上下文拒绝实际卸载。

这是我的 HostAssemblyLoadContext 实现:

public class HostAssemblyLoadContext : AssemblyLoadContext
{
    private readonly AssemblyDependencyResolver _resolver;

    public HostAssemblyLoadContext(string pluginPath) : base(isCollectible: true)
    {
        _resolver = new AssemblyDependencyResolver(pluginPath);
    }

    protected override Assembly? Load(AssemblyName name)
    {
        string? assemblyPath = _resolver.ResolveAssemblyToPath(name);
        if (assemblyPath != null)
            return LoadFromAssemblyPath(assemblyPath);

        string filePath = $"{name.FullName.Split(',')[0]}.dll";
        if(File.Exists(filePath))
            return Assembly.LoadFrom(filePath);

        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的加载器代码:

[MethodImpl(MethodImplOptions.NoInlining)]
private static …
Run Code Online (Sandbox Code Playgroud)

c# asp.net appdomain .net-assembly asp.net-core

5
推荐指数
0
解决办法
926
查看次数

如何从可变参数模板参数创建 std::tuple&lt;&gt; ?

我有一个使用此模板声明的类:template <typename ...Args>。在其中,我有一个声明为std::vector<std::tuple<Args...>> vec;存储模板指定的数据条目的列表。我还有一个函数声明如下:

void AddVertex(Args... data)
{
    // vec.push_back(std::tuple<Args...>(data));
}
Run Code Online (Sandbox Code Playgroud)

在此函数中,我想将 Args... 元组添加到向量中。这可能吗?我尝试使用注释中的代码,但编译器给我一个错误,指出“参数包必须在此上下文中扩展”。

解决方案不起作用,因为元组的模板参数已经扩展。

c++ templates variadic-functions visual-c++ variadic-templates

4
推荐指数
1
解决办法
2116
查看次数