简体   繁体   English

System.NullReferenceException 从 appSettings.json 访问 Base URL

[英]System.NullReferenceException on accessing the Base URL from the appSettings.json

I have the Base URL within the appsettings.json like below我在 appsettings.json 中有 Base URL,如下所示

  "RM": {
    "BaseAddress": "https://rm-dev.abc.org/"
  },

With in the Class where I am trying to make a call this endpoint在 Class 中,我正在尝试调用此端点

public class InventorySearchLogic
    {
        private readonly SMContext _context;
        private readonly IConfiguration _iconfiguration;
        public InventorySearchLogic(SMContext context, IConfiguration iconfiguration)
        {
            _context = context;
            _iconfiguration = iconfiguration;
        }

        public InventorySearchLogic(SMContext context)
        {
        } 

  public async Task<string> GetRoomID(string roomName)
        {
            //string rmID = "";
            using (var client = new HttpClient())
            {
                RmRoom retRoom = new RmRoom();
                client.BaseAddress = new Uri(_iconfiguration.GetSection("RM").GetSection("BaseAddress").Value);
                client.DefaultRequestHeaders.Accept.Clear();

When debugging it throws error like System.NullReferenceException: Message=Object reference not set to an instance of an object. how to access the base URL from appsettings.json调试时会抛出类似System.NullReferenceException: Message=Object reference not set to an instance of an object.如何从 appsettings.json 访问基础 URL

I am not sure how to use the ConfigurationBuilder() as I have different apSettings.json file one for each environment like appsettings.Development.json , appsettings.QA.json , appsettings.PROD.json我不确定如何使用ConfigurationBuilder() ,因为我有不同的 apSettings.json 文件,每个环境都有一个,例如appsettings.Development.jsonappsettings.QA.jsonappsettings.PROD.json

在此处输入图像描述

Below is my Startup下面是我的启动

    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.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));

            services.AddControllersWithViews();
            services.AddSession();
            services.AddMemoryCache();
            services.AddDbContextPool<SurplusMouseContext>(options =>
                {
                    options.UseSqlServer(Configuration.GetConnectionString("SMConnectionStrings"),
                  sqlServerOptionsAction: sqlOptions =>
                  {
                      sqlOptions.EnableRetryOnFailure();
                  });
                });
            services.AddHttpContextAccessor();
            services.AddControllersWithViews(options =>
            {
                var policy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .Build();
                options.Filters.Add(new AuthorizeFilter(policy));
            });
            services.AddRazorPages()
                 .AddMicrosoftIdentityUI();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
            app.UseSession();
            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Customers}/{action=Index}/{id?}");
            });
        }
    }

Program.cs程序.cs

 public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }

在此处输入图像描述

You're already injecting an IConfiguration in your service and saving it as _iconfiguration .您已经在服务中注入IConfiguration并将其保存为_iconfiguration Assuming that's not the null value , then simply use .GetValue to retrieve a value.假设这不是 null 值,那么只需使用.GetValue来检索一个值。

string baseAddress = _iconfiguration.GetSection("RM").GetValue<string>("BaseAddress");

Read more about ASP.Net configuration阅读有关ASP.Net 配置的更多信息


Well, it seems that _iconfiguration is also null.嗯,好像_iconfiguration也是null。

You've indicated in the comments that you're creating an instance of InventorySearchLogic from a controller , such as您在评论中指出您正在从 controller创建InventorySearchLogic的实例,例如

// inside controller logic
var searchLogic = new InventorySearchLogic(_context, _iconfiguration);

This is the wrong approach.这是错误的做法。 Instead, you should register this class as a DI service (although you should also add an interface, it's not necessary right now).相反,您应该将此 class 注册为 DI 服务(尽管您还应该添加一个接口,但现在没有必要)。

In your Startup's ConfigureServices method, add在您的 Startup 的ConfigureServices方法中,添加

services.AddTransient<InventorySearchLogic>();

Then instead of manually creating a variable of type InventorySearchLogic , request it though DI然后不是手动创建InventorySearchLogic类型的变量,而是通过 DI 请求它

// your controller constructor
private readonly InventorySearchLogic searchLogic;
public MyController(InventorySearchLogic searchLogic)
{
    this.searchLogic = searchLogic;
}

This way, InventorySearchLogic's constructor correctly gets the DI services it's looking for.这样,InventorySearchLogic 的构造函数就可以正确地获取它正在寻找的 DI 服务。 You will have to move the SMContext context .您将必须移动SMContext context Maybe move that to the method's parameters?也许将其移至方法的参数?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM