ASP.NET 核心 2.1 - 选项模式 - 访问选项不会 return 绑定的实例 class
ASP.NET Core 2.1 - Options pattern - accessing options doesn't return instance of the bound class
我正在尝试按照 this example from Microsoft Docs 从我的 ASP.NET Core 2.1 应用程序中的 appsettings.json 文件中检索一些配置选项。
我绑定了class
public class MailServer
{
public string Host { get; set; }
public int Port { get; set; }
public bool UseSSL { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string FromAddress { get; set; }
public MailServer()
{
}
}
到Startup.cs中的配置
public void ConfigureServices(IServiceCollection services)
{
// .....
services.Configure<MailServer>(Configuration.GetSection("MailServer"));
// .....
services.AddSingleton<IScheduledTask, ScheduledTask>();
}
在启动时,我还添加了 ScheduledTask 作为单例,以便从特定的 class 访问上下文 - 这也是我想访问选项的地方。
public interface IScheduledTask
{
void MonitorCloudHosts();
}
public class ScheduledTask : IScheduledTask
{
private readonly IServiceProvider _ServiceProvider;
private readonly MailServer _mailServer;
// note here you ask to the injector for IServiceProvider
public ScheduledTask(IServiceProvider serviceProvider, IOptions<MailServer> optionsAccessor)
{
_ServiceProvider = serviceProvider;
_mailServer = optionsAccessor.Value;
}
public void MonitorCloudHosts()
{
// Do some stuff
var xyz = _mailServer.Host;
}
}
这是我的 appsettings.json 文件:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"CloudMonitorConnection": "Server=.\SQLEXPRESS;Database=CloudMonitor;Integrated Security=SSPI;MultipleActiveResultSets=true;",
"HangFireConnection": "Server=.\SQLEXPRESS;Database=HangFire;Integrated Security=SSPI;"
},
"MailServer": {
"Host": "smtp.gmail.com",
"Port": "587",
"UseSSL": "True",
"Username": "xxxxxxx@gmail.com",
"Password": "xxxxxxx",
"FromAddress": "xxxxxxx<xxxxxxx@gmail.com>"
}
}
编译器在调用 _mailServer.Host 时给出错误说 "An object reference is required..." - 但在 optionsAccessor.Value
.
上没有给出错误
不应该 optionsAccessor.Value
return MailServer 的实例吗?我在这里犯了一些新手错误吗?
属性 MailServer
class 的 UseSSL
是 bool
但在 appsettings.json 中设置为 "True"
。
您应该这样更改 appsettings.json:
"MailServer": {
"Host": "smtp.gmail.com",
"Port": 587,
"UseSSL": true,
"Username": "xxxxxxx@gmail.com",
"Password": "xxxxxxx",
"FromAddress": "xxxxxxx<xxxxxxx@gmail.com>"
}
编辑:
我用这段代码创建了一个空项目并进行了编译。可能是using statement出错了,或者开启了严格模式?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace samp
{
public class MailServer
{
public string Host { get; set; }
public int Port { get; set; }
public bool UseSSL { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string FromAddress { get; set; }
public MailServer()
{
}
}
public interface IScheduledTask
{
void MonitorCloudHosts();
}
public class ScheduledTask : IScheduledTask
{
private readonly IServiceProvider _ServiceProvider;
private readonly MailServer _mailServer;
// note here you ask to the injector for IServiceProvider
public ScheduledTask(IServiceProvider serviceProvider, IOptions<MailServer> optionsAccessor)
{
_ServiceProvider = serviceProvider;
_mailServer = optionsAccessor.Value;
}
public void MonitorCloudHosts()
{
// Do some stuff
var xyz = _mailServer.Host;
}
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.Configure<MailServer>(Configuration.GetSection("MailServer"));
services.AddSingleton<IScheduledTask, ScheduledTask>();
}
// 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.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
}
}
我正在尝试按照 this example from Microsoft Docs 从我的 ASP.NET Core 2.1 应用程序中的 appsettings.json 文件中检索一些配置选项。
我绑定了class
public class MailServer
{
public string Host { get; set; }
public int Port { get; set; }
public bool UseSSL { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string FromAddress { get; set; }
public MailServer()
{
}
}
到Startup.cs中的配置
public void ConfigureServices(IServiceCollection services)
{
// .....
services.Configure<MailServer>(Configuration.GetSection("MailServer"));
// .....
services.AddSingleton<IScheduledTask, ScheduledTask>();
}
在启动时,我还添加了 ScheduledTask 作为单例,以便从特定的 class 访问上下文 - 这也是我想访问选项的地方。
public interface IScheduledTask
{
void MonitorCloudHosts();
}
public class ScheduledTask : IScheduledTask
{
private readonly IServiceProvider _ServiceProvider;
private readonly MailServer _mailServer;
// note here you ask to the injector for IServiceProvider
public ScheduledTask(IServiceProvider serviceProvider, IOptions<MailServer> optionsAccessor)
{
_ServiceProvider = serviceProvider;
_mailServer = optionsAccessor.Value;
}
public void MonitorCloudHosts()
{
// Do some stuff
var xyz = _mailServer.Host;
}
}
这是我的 appsettings.json 文件:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"CloudMonitorConnection": "Server=.\SQLEXPRESS;Database=CloudMonitor;Integrated Security=SSPI;MultipleActiveResultSets=true;",
"HangFireConnection": "Server=.\SQLEXPRESS;Database=HangFire;Integrated Security=SSPI;"
},
"MailServer": {
"Host": "smtp.gmail.com",
"Port": "587",
"UseSSL": "True",
"Username": "xxxxxxx@gmail.com",
"Password": "xxxxxxx",
"FromAddress": "xxxxxxx<xxxxxxx@gmail.com>"
}
}
编译器在调用 _mailServer.Host 时给出错误说 "An object reference is required..." - 但在 optionsAccessor.Value
.
不应该 optionsAccessor.Value
return MailServer 的实例吗?我在这里犯了一些新手错误吗?
属性 MailServer
class 的 UseSSL
是 bool
但在 appsettings.json 中设置为 "True"
。
您应该这样更改 appsettings.json:
"MailServer": {
"Host": "smtp.gmail.com",
"Port": 587,
"UseSSL": true,
"Username": "xxxxxxx@gmail.com",
"Password": "xxxxxxx",
"FromAddress": "xxxxxxx<xxxxxxx@gmail.com>"
}
编辑: 我用这段代码创建了一个空项目并进行了编译。可能是using statement出错了,或者开启了严格模式?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace samp
{
public class MailServer
{
public string Host { get; set; }
public int Port { get; set; }
public bool UseSSL { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string FromAddress { get; set; }
public MailServer()
{
}
}
public interface IScheduledTask
{
void MonitorCloudHosts();
}
public class ScheduledTask : IScheduledTask
{
private readonly IServiceProvider _ServiceProvider;
private readonly MailServer _mailServer;
// note here you ask to the injector for IServiceProvider
public ScheduledTask(IServiceProvider serviceProvider, IOptions<MailServer> optionsAccessor)
{
_ServiceProvider = serviceProvider;
_mailServer = optionsAccessor.Value;
}
public void MonitorCloudHosts()
{
// Do some stuff
var xyz = _mailServer.Host;
}
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.Configure<MailServer>(Configuration.GetSection("MailServer"));
services.AddSingleton<IScheduledTask, ScheduledTask>();
}
// 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.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
}
}