【问题标题】:Unable to resolve service of ASP.NET sample project (using core 1 instead of 2)无法解析 ASP.NET 示例项目的服务(使用核心 1 而不是 2)
【发布时间】:2019-01-07 14:23:37
【问题描述】:

我使用的是 ASP.Net core 1 而不是 2,并尝试让 OpenIdDict 的示例在我的系统上运行。我做了一些小改动,使项目可以为我构建。但是我在调​​试时遇到错误并且不知道如何处理它。有人对我有想法/提示吗?非常感谢!

System.InvalidOperationException:无法解析服务类型 'Microsoft.Extensions.Configuration.IConfiguration' 尝试 激活“AuthorizationServer.Startup”。在 Microsoft.Extensions.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider 提供者)在 Microsoft.AspNetCore.Hosting.Internal.StartupLoader.LoadMethods(IServiceProvider 服务,类型启动类型,字符串环境名称)在 Microsoft.AspNetCore.Hosting.WebHostBuilderExtensions.c__DisplayClass1_0.b__1(IServiceProvider sp) 在 Microsoft.Extensions.DependencyInjection.ServiceProvider.ScopedCallSite.Invoke(ServiceProvider 提供者)在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider 提供者,类型 serviceType) 在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider 提供者)在 Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureStartup() 在 Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices() 在 Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

编辑:添加程序代码

using System;
using System.Threading.Tasks;
using AuthorizationServer.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using OpenIddict.Abstractions;
using OpenIddict.Core;
using OpenIddict.EntityFrameworkCore.Models;
using System.Net.Http;
using Microsoft.AspNetCore.Authentication.Cookies;

namespace AuthorizationServer
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            var connection = @"...";
            services.AddDbContext<ApplicationDbContext>(options =>
            {
                options.UseSqlServer(connection);

                options.UseOpenIddict();
            });

            services.AddOpenIddict()

                .AddCore(options =>
                {
                    options.UseEntityFrameworkCore()
                           .UseDbContext<ApplicationDbContext>();
                })

                .AddServer(options =>
                {
                    options.UseMvc();

                    options.EnableTokenEndpoint("/connect/token");

                    options.AllowClientCredentialsFlow();

                    options.DisableHttpsRequirement();
                })

                .AddValidation();

            services.AddSingleton(Configuration); //changed here
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseDeveloperExceptionPage();

            app.UseOAuthValidation();
            //app.UseAuthentication();

            app.UseMvcWithDefaultRoute();

            app.UseWelcomePage();

            InitializeAsync(app.ApplicationServices).GetAwaiter().GetResult();
        }

        private async Task InitializeAsync(IServiceProvider services)
        {
            using (var scope = services.GetRequiredService<IServiceScopeFactory>().CreateScope())
            {
                var context = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
                await context.Database.EnsureCreatedAsync();

                var manager = scope.ServiceProvider.GetRequiredService<OpenIddictApplicationManager<OpenIddictApplication>>();

                if (await manager.FindByClientIdAsync("console") == null)
                {
                    var descriptor = new OpenIddictApplicationDescriptor
                    {
                        ClientId = "console",
                        ClientSecret = "388D45FA-B36B-4988-BA59-B187D329C207",
                        DisplayName = "My client application",
                        Permissions =
                        {
                            OpenIddictConstants.Permissions.Endpoints.Token,
                            OpenIddictConstants.Permissions.GrantTypes.ClientCredentials
                        }
                    };

                    await manager.CreateAsync(descriptor);
                }
            }
        }
    }
}

程序.cs

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace AuthorizationServer
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            var configuration = new ConfigurationBuilder()
                .AddEnvironmentVariables()
                .AddCommandLine(args)
                .Build();

            var host = new WebHostBuilder()
                .ConfigureLogging(options => options.AddConsole())
                .ConfigureLogging(options => options.AddDebug())
                .UseConfiguration(configuration)
                .UseIISIntegration()
                .UseKestrel()
                .UseStartup<Startup>()
                .Build();

            host.Run();
        }
    }
}

【问题讨论】:

    标签: c# asp.net-core


    【解决方案1】:

    在 ASP.NET Core 1.x 中无法将 IConfiguration 注入到您的 Startup 构造函数中。相反,您可以注入 IHostingEnvironment 并构建自己的 IConfiguration 实例,如下所示:

    public Startup(IHostingEnvironment env)
    {
        Configuration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json")
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables()
            .Build();
    }
    

    如果您没有任何 appsettings.json 文件,则可以排除 AddJsonFile 行 - 我所包含的只是基于 ASP.NET Core 1.x 生成的模板的示例。

    【讨论】:

    • iirc 1.x 模板中的Configuration 属性,如果类型为IConfigurationRoot,而不是IConfiguration。如果注册正确,注射应该起作用。但我不建议这样做(将基础设施泄漏到您的服务中,最好使用IOption&lt;T&gt;
    • @Tseng 我也认为是对的 - IConfigurationRoot。 OP 已经在使用IConfiguration,所以我用它来保持简单而不会丢失任何东西。我也同意IOptions&lt;T&gt; 的东西——这通常是很好的建议,但鉴于 OP 只是试图构建一个现有的样本,它可能在这里脱离上下文(imo)。感谢您的意见。
    • IConfigurationRoot 继承自 IConfiguration 因此它可以用作替代品,但注册必须是 services.AddSingleton&lt;IConfigurationRoot&gt;(Configuration); 而不是 services.AddSingleton(Configuration); (如您已删除的答案),因为后者为IConfigurationRoot 创建一个注册,但没有为IConfiguration 创建一个注册。如果你想要两个都需要注册bothIConfigurationRootIConfiguration显式
    • @Tseng 我删除了另一个答案,因为我们不需要 DI 中的 eitherIConfigurationIConfigurationRoot 来解决手头的问题。我错误地认为错误是Startup 之后的错误,但实际上是Startup 构造函数本身导致了错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    相关资源
    最近更新 更多