ASP.NET Core Integration Test works locally but throws null reference exception when running in production environmentAsp.Net Core Challenge returns Null URI Exception errorHow to fix 500 Internal Server Error for POST integration tests using TestServer and Antiforgery? ASP.NET Coreasp.net mvc application throw controller exception when application is deployedAn exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll but was not handled in user codeASP.Net Core Integration TestingUnity Dependency injection automatically expires after a particular time.. Why?Dependency injection in ASP.NET Core 2 throws exceptionError occurred when trying to create a controller of type 'EmployeeController'. Make sure controller has a parameterless public constructorASP.NET Core running two TestServer for Integration TestingMocking ODataQueryOptions on .Net CoreAfter retargeting to .NET Core 2.1 getting new error System.ObjectDisposedException: Cannot access a disposed objectThe reference to external elements from the source named 'xyz.dacpac' could not be resolved
Axiom of Choice in General Topology
How do I write real-world stories separate from my country of origin?
Were there any developed countries that became "undeveloped" for reasons other than war?
Why is the Psionic Artificer considered to be better than all other tier 1 classes?
Is there a word for pant sleeves?
Expand a hexagon
Must every right-inverse of a linear transformation be a linear transformation?
What is the required burn to keep a satellite at a Lagrangian point?
can conjure barrage stack with martial adept- disarming or tripping attack?
Can diplomats be allowed on the flight deck of a commercial European airline?
Why is 'additive' EQ more difficult to use than 'subtractive'?
Nunc est bibendum: gerund or gerundive?
What defines a person who is circumcised "of the heart"?
What to call a small, open stone or cement reservoir that supplies fresh water from a spring or other natural source?
How could the B-29 bomber back up under its own power?
How to remove unwanted horizontal line from diagbox
Managing heat dissipation in a magic wand
Results relying on higher derived algebraic geometry
Island Perimeter
Are there historical examples of audiences drawn to a work that was "so bad it's good"?
Coloring lines in a graph the same color if they are the same length
Make the `diff` command look only for differences from a specified range of lines
Ribbon Cable Cross Talk - Is there a fix after the fact?
Why "strap-on" boosters, and how do other people say it?
ASP.NET Core Integration Test works locally but throws null reference exception when running in production environment
Asp.Net Core Challenge returns Null URI Exception errorHow to fix 500 Internal Server Error for POST integration tests using TestServer and Antiforgery? ASP.NET Coreasp.net mvc application throw controller exception when application is deployedAn exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll but was not handled in user codeASP.Net Core Integration TestingUnity Dependency injection automatically expires after a particular time.. Why?Dependency injection in ASP.NET Core 2 throws exceptionError occurred when trying to create a controller of type 'EmployeeController'. Make sure controller has a parameterless public constructorASP.NET Core running two TestServer for Integration TestingMocking ODataQueryOptions on .Net CoreAfter retargeting to .NET Core 2.1 getting new error System.ObjectDisposedException: Cannot access a disposed objectThe reference to external elements from the source named 'xyz.dacpac' could not be resolved
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I have an ASP.NET Core 2.2 Razor Pages Web App that I have written some integration tests for following the official guide.
I can get the tests to run locally using dotnet test or the test runners built into Visual Studio. However, on the build server (Azure DevOps Hosted 2017 agent) the tests will return a 500 error. I thought it might be related to user secrets as stated on Scott Hanselman's guide but I am still getting the same error, even after implementing some of his suggested fixes (I don't believe I need all of them) :
- Added
builder.AddUserSecrets<Startup>();to Startup. - Implemented a
CustomWebApplicationFactoryto set the environment to "Development" - code below has this as "Production" to reproduce the failure.
I also sanity checked against this guide which is more controller focused but since I only care about the response codes at this stage it serves my purpose. I have downloaded the verbose logs and they don't shed any light on the issue.
My code is below:
CustomWebApplicationFactory:
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
namespace WebPortal.Int.Tests
/// <summary>
/// Based on https://fullstackmark.com/post/20/painless-integration-testing-with-aspnet-core-web-api
/// </summary>
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<Startup> where TStartup : class
public CustomWebApplicationFactory()
protected override void ConfigureWebHost(IWebHostBuilder builder)
builder
.ConfigureTestServices(
services =>
services.Configure(AzureADDefaults.OpenIdScheme, (System.Action<OpenIdConnectOptions>)(o =>
// CookieContainer doesn't allow cookies from other paths
o.CorrelationCookie.Path = "/";
o.NonceCookie.Path = "/";
));
)
.UseEnvironment("Production")
.UseStartup<Startup>();
AuthenticationTests:
using Microsoft.AspNetCore.Mvc.Testing;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;
namespace WebPortal.Int.Tests
public class AuthenticationTests : IClassFixture<CustomWebApplicationFactory<Startup>>
private HttpClient _httpClient get;
public AuthenticationTests(CustomWebApplicationFactory<Startup> fixture)
WebApplicationFactoryClientOptions webAppFactoryClientOptions = new WebApplicationFactoryClientOptions
// Disallow redirect so that we can check the following: Status code is redirect and redirect url is login url
// As per https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2#test-a-secure-endpoint
AllowAutoRedirect = false
;
_httpClient = fixture.CreateClient(webAppFactoryClientOptions);
[Theory]
[InlineData("/")]
[InlineData("/Index")]
[InlineData("/Error")]
public async Task Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(string url)
// Act
HttpResponseMessage response = await _httpClient.GetAsync(url);
// Assert
try
response.EnsureSuccessStatusCode();
catch (HttpRequestException ex)
Console.WriteLine(ex.Message, ex.InnerException.Message);
Startup:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WebPortal.Authentication;
using WebPortal.Common.ConfigurationOptions;
using WebPortal.DataAccess;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Http;
namespace WebPortal
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.Configure<CookiePolicyOptions>(options =>
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
);
services.AddOptions<PowerBiSettings>()
.Bind(Configuration.GetSection("PowerBI"))
.ValidateDataAnnotations()
.Validate(o => o.AreSettingsValid());
services.AddOptions<AzureActiveDirectorySettings>()
.Bind(Configuration.GetSection("AzureAd"))
.ValidateDataAnnotations()
.Validate(o => o.AreSettingsValid());
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options))
.AddCookie();
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
);
services.AddTransient<Authentication.IAuthenticationHandler, AuthenticationHandler>();
services.AddTransient<IReportRepository, ReportRepository>();
services.AddHttpContextAccessor();
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddRazorPagesOptions(options =>
options.Conventions.AuthorizePage("/Reports");
);
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
var builder = new ConfigurationBuilder();
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
builder.AddUserSecrets<Startup>();
else
app.UseExceptionHandler("/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.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc();
Error output:
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.1 (64-bit .NET Core 4.6.27317.07)
[xUnit.net 00:00:01.30] Discovering: WebPortal.Int.Tests
[xUnit.net 00:00:01.40] Discovered: WebPortal.Int.Tests
[xUnit.net 00:00:01.41] Starting: WebPortal.Int.Tests
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
User profile is available. Using 'C:UsersVssAdministratorAppDataLocalASP.NETDataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[58]
Creating key dd820f09-8139-4d7d-954a-399923660f42 with creation date 2019-03-18 22:13:27Z, activation date 2019-03-18 22:13:27Z, and expiration date 2019-06-16 22:13:27Z.
info: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[39]
Writing data to file 'C:UsersVssAdministratorAppDataLocalASP.NETDataProtection-Keyskey-dd820f09-8139-4d7d-954a-399923660f42.xml'.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/2.0 GET http://localhost/Index
warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
Failed to determine the https port for redirect.
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.ArgumentNullException: Value cannot be null.
Parameter name: uriString
at System.Uri..ctor(String uriString)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[3]
An exception was thrown attempting to execute the error handler.
System.ArgumentNullException: Value cannot be null.
Parameter name: uriString
at System.Uri..ctor(String uriString)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 449.9633ms 500
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/2.0 GET http://localhost/Error
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.ArgumentNullException: Value cannot be null.
Parameter name: uriString
at System.Uri..ctor(String uriString)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(url: "/Index") [FAIL]
[xUnit.net 00:00:02.61] System.ArgumentNullException : Value cannot be null.
[xUnit.net 00:00:02.61] Parameter name: uriString
[xUnit.net 00:00:02.61] Stack Trace:
[xUnit.net 00:00:02.61] at System.Uri..ctor(String uriString)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
[xUnit.net 00:00:02.61] at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
[xUnit.net 00:00:02.61] --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:02.61] at System.Lazy`1.CreateValue()
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.TestHost.HttpContextBuilder.<>c__DisplayClass10_0.<<SendAsync>b__0>d.MoveNext()
[xUnit.net 00:00:02.61] --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.TestHost.ClientHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Mvc.Testing.Handlers.CookieContainerHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Mvc.Testing.Handlers.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)[xUnit.net 00:00:02.63] WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(url: "/Error") [FAIL]
[xUnit.net 00:00:02.64] WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(url: "") [FAIL]
[xUnit.net 00:00:02.61] at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
[xUnit.net 00:00:02.61] D:a1sWebPortal.Int.TestsAuthenticationTests.cs(24,0): at WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(String url)
[xUnit.net 00:00:02.61] --- End of stack trace from previous location where exception was thrown ---
edit
It isn't very clear to me where/why I am getting a null reference because as far as I can tell my OpenIdConnectOptions configuration is correct (and it works with AAD SSO).
c# asp.net-core
add a comment |
I have an ASP.NET Core 2.2 Razor Pages Web App that I have written some integration tests for following the official guide.
I can get the tests to run locally using dotnet test or the test runners built into Visual Studio. However, on the build server (Azure DevOps Hosted 2017 agent) the tests will return a 500 error. I thought it might be related to user secrets as stated on Scott Hanselman's guide but I am still getting the same error, even after implementing some of his suggested fixes (I don't believe I need all of them) :
- Added
builder.AddUserSecrets<Startup>();to Startup. - Implemented a
CustomWebApplicationFactoryto set the environment to "Development" - code below has this as "Production" to reproduce the failure.
I also sanity checked against this guide which is more controller focused but since I only care about the response codes at this stage it serves my purpose. I have downloaded the verbose logs and they don't shed any light on the issue.
My code is below:
CustomWebApplicationFactory:
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
namespace WebPortal.Int.Tests
/// <summary>
/// Based on https://fullstackmark.com/post/20/painless-integration-testing-with-aspnet-core-web-api
/// </summary>
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<Startup> where TStartup : class
public CustomWebApplicationFactory()
protected override void ConfigureWebHost(IWebHostBuilder builder)
builder
.ConfigureTestServices(
services =>
services.Configure(AzureADDefaults.OpenIdScheme, (System.Action<OpenIdConnectOptions>)(o =>
// CookieContainer doesn't allow cookies from other paths
o.CorrelationCookie.Path = "/";
o.NonceCookie.Path = "/";
));
)
.UseEnvironment("Production")
.UseStartup<Startup>();
AuthenticationTests:
using Microsoft.AspNetCore.Mvc.Testing;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;
namespace WebPortal.Int.Tests
public class AuthenticationTests : IClassFixture<CustomWebApplicationFactory<Startup>>
private HttpClient _httpClient get;
public AuthenticationTests(CustomWebApplicationFactory<Startup> fixture)
WebApplicationFactoryClientOptions webAppFactoryClientOptions = new WebApplicationFactoryClientOptions
// Disallow redirect so that we can check the following: Status code is redirect and redirect url is login url
// As per https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2#test-a-secure-endpoint
AllowAutoRedirect = false
;
_httpClient = fixture.CreateClient(webAppFactoryClientOptions);
[Theory]
[InlineData("/")]
[InlineData("/Index")]
[InlineData("/Error")]
public async Task Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(string url)
// Act
HttpResponseMessage response = await _httpClient.GetAsync(url);
// Assert
try
response.EnsureSuccessStatusCode();
catch (HttpRequestException ex)
Console.WriteLine(ex.Message, ex.InnerException.Message);
Startup:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WebPortal.Authentication;
using WebPortal.Common.ConfigurationOptions;
using WebPortal.DataAccess;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Http;
namespace WebPortal
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.Configure<CookiePolicyOptions>(options =>
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
);
services.AddOptions<PowerBiSettings>()
.Bind(Configuration.GetSection("PowerBI"))
.ValidateDataAnnotations()
.Validate(o => o.AreSettingsValid());
services.AddOptions<AzureActiveDirectorySettings>()
.Bind(Configuration.GetSection("AzureAd"))
.ValidateDataAnnotations()
.Validate(o => o.AreSettingsValid());
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options))
.AddCookie();
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
);
services.AddTransient<Authentication.IAuthenticationHandler, AuthenticationHandler>();
services.AddTransient<IReportRepository, ReportRepository>();
services.AddHttpContextAccessor();
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddRazorPagesOptions(options =>
options.Conventions.AuthorizePage("/Reports");
);
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
var builder = new ConfigurationBuilder();
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
builder.AddUserSecrets<Startup>();
else
app.UseExceptionHandler("/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.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc();
Error output:
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.1 (64-bit .NET Core 4.6.27317.07)
[xUnit.net 00:00:01.30] Discovering: WebPortal.Int.Tests
[xUnit.net 00:00:01.40] Discovered: WebPortal.Int.Tests
[xUnit.net 00:00:01.41] Starting: WebPortal.Int.Tests
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
User profile is available. Using 'C:UsersVssAdministratorAppDataLocalASP.NETDataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[58]
Creating key dd820f09-8139-4d7d-954a-399923660f42 with creation date 2019-03-18 22:13:27Z, activation date 2019-03-18 22:13:27Z, and expiration date 2019-06-16 22:13:27Z.
info: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[39]
Writing data to file 'C:UsersVssAdministratorAppDataLocalASP.NETDataProtection-Keyskey-dd820f09-8139-4d7d-954a-399923660f42.xml'.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/2.0 GET http://localhost/Index
warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
Failed to determine the https port for redirect.
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.ArgumentNullException: Value cannot be null.
Parameter name: uriString
at System.Uri..ctor(String uriString)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[3]
An exception was thrown attempting to execute the error handler.
System.ArgumentNullException: Value cannot be null.
Parameter name: uriString
at System.Uri..ctor(String uriString)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 449.9633ms 500
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/2.0 GET http://localhost/Error
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.ArgumentNullException: Value cannot be null.
Parameter name: uriString
at System.Uri..ctor(String uriString)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(url: "/Index") [FAIL]
[xUnit.net 00:00:02.61] System.ArgumentNullException : Value cannot be null.
[xUnit.net 00:00:02.61] Parameter name: uriString
[xUnit.net 00:00:02.61] Stack Trace:
[xUnit.net 00:00:02.61] at System.Uri..ctor(String uriString)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
[xUnit.net 00:00:02.61] at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
[xUnit.net 00:00:02.61] --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:02.61] at System.Lazy`1.CreateValue()
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.TestHost.HttpContextBuilder.<>c__DisplayClass10_0.<<SendAsync>b__0>d.MoveNext()
[xUnit.net 00:00:02.61] --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.TestHost.ClientHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Mvc.Testing.Handlers.CookieContainerHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Mvc.Testing.Handlers.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)[xUnit.net 00:00:02.63] WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(url: "/Error") [FAIL]
[xUnit.net 00:00:02.64] WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(url: "") [FAIL]
[xUnit.net 00:00:02.61] at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
[xUnit.net 00:00:02.61] D:a1sWebPortal.Int.TestsAuthenticationTests.cs(24,0): at WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(String url)
[xUnit.net 00:00:02.61] --- End of stack trace from previous location where exception was thrown ---
edit
It isn't very clear to me where/why I am getting a null reference because as far as I can tell my OpenIdConnectOptions configuration is correct (and it works with AAD SSO).
c# asp.net-core
2
Hi, may be stupid question and you have already checked it. But have you tried to move: "builder.AddUserSecrets<Startup>();" outside of env.IsDevelopment() ?
– Nikolay
Mar 20 at 8:20
1
Seeing your stracktrace, I'm pretty sure your question is answered here
– Jesse de Wit
Mar 20 at 18:20
@Nikolay yes I have tried this thank you.
– Matt Stannett
Mar 20 at 20:28
@JessedeWit that suggestion didn't fix it my issue but it did put me onto the fact that myAzureAdconfiguration wasn't being loaded properly during the tests. Hardcoding the values in worked then I realised that I hadn't called.Build()on myConfigurationBuilderand assigned the value to the Configuration object. This also meant that I moved the code to include the secrets into theStartupconstructor.
– Matt Stannett
Mar 20 at 20:30
add a comment |
I have an ASP.NET Core 2.2 Razor Pages Web App that I have written some integration tests for following the official guide.
I can get the tests to run locally using dotnet test or the test runners built into Visual Studio. However, on the build server (Azure DevOps Hosted 2017 agent) the tests will return a 500 error. I thought it might be related to user secrets as stated on Scott Hanselman's guide but I am still getting the same error, even after implementing some of his suggested fixes (I don't believe I need all of them) :
- Added
builder.AddUserSecrets<Startup>();to Startup. - Implemented a
CustomWebApplicationFactoryto set the environment to "Development" - code below has this as "Production" to reproduce the failure.
I also sanity checked against this guide which is more controller focused but since I only care about the response codes at this stage it serves my purpose. I have downloaded the verbose logs and they don't shed any light on the issue.
My code is below:
CustomWebApplicationFactory:
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
namespace WebPortal.Int.Tests
/// <summary>
/// Based on https://fullstackmark.com/post/20/painless-integration-testing-with-aspnet-core-web-api
/// </summary>
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<Startup> where TStartup : class
public CustomWebApplicationFactory()
protected override void ConfigureWebHost(IWebHostBuilder builder)
builder
.ConfigureTestServices(
services =>
services.Configure(AzureADDefaults.OpenIdScheme, (System.Action<OpenIdConnectOptions>)(o =>
// CookieContainer doesn't allow cookies from other paths
o.CorrelationCookie.Path = "/";
o.NonceCookie.Path = "/";
));
)
.UseEnvironment("Production")
.UseStartup<Startup>();
AuthenticationTests:
using Microsoft.AspNetCore.Mvc.Testing;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;
namespace WebPortal.Int.Tests
public class AuthenticationTests : IClassFixture<CustomWebApplicationFactory<Startup>>
private HttpClient _httpClient get;
public AuthenticationTests(CustomWebApplicationFactory<Startup> fixture)
WebApplicationFactoryClientOptions webAppFactoryClientOptions = new WebApplicationFactoryClientOptions
// Disallow redirect so that we can check the following: Status code is redirect and redirect url is login url
// As per https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2#test-a-secure-endpoint
AllowAutoRedirect = false
;
_httpClient = fixture.CreateClient(webAppFactoryClientOptions);
[Theory]
[InlineData("/")]
[InlineData("/Index")]
[InlineData("/Error")]
public async Task Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(string url)
// Act
HttpResponseMessage response = await _httpClient.GetAsync(url);
// Assert
try
response.EnsureSuccessStatusCode();
catch (HttpRequestException ex)
Console.WriteLine(ex.Message, ex.InnerException.Message);
Startup:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WebPortal.Authentication;
using WebPortal.Common.ConfigurationOptions;
using WebPortal.DataAccess;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Http;
namespace WebPortal
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.Configure<CookiePolicyOptions>(options =>
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
);
services.AddOptions<PowerBiSettings>()
.Bind(Configuration.GetSection("PowerBI"))
.ValidateDataAnnotations()
.Validate(o => o.AreSettingsValid());
services.AddOptions<AzureActiveDirectorySettings>()
.Bind(Configuration.GetSection("AzureAd"))
.ValidateDataAnnotations()
.Validate(o => o.AreSettingsValid());
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options))
.AddCookie();
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
);
services.AddTransient<Authentication.IAuthenticationHandler, AuthenticationHandler>();
services.AddTransient<IReportRepository, ReportRepository>();
services.AddHttpContextAccessor();
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddRazorPagesOptions(options =>
options.Conventions.AuthorizePage("/Reports");
);
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
var builder = new ConfigurationBuilder();
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
builder.AddUserSecrets<Startup>();
else
app.UseExceptionHandler("/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.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc();
Error output:
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.1 (64-bit .NET Core 4.6.27317.07)
[xUnit.net 00:00:01.30] Discovering: WebPortal.Int.Tests
[xUnit.net 00:00:01.40] Discovered: WebPortal.Int.Tests
[xUnit.net 00:00:01.41] Starting: WebPortal.Int.Tests
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
User profile is available. Using 'C:UsersVssAdministratorAppDataLocalASP.NETDataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[58]
Creating key dd820f09-8139-4d7d-954a-399923660f42 with creation date 2019-03-18 22:13:27Z, activation date 2019-03-18 22:13:27Z, and expiration date 2019-06-16 22:13:27Z.
info: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[39]
Writing data to file 'C:UsersVssAdministratorAppDataLocalASP.NETDataProtection-Keyskey-dd820f09-8139-4d7d-954a-399923660f42.xml'.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/2.0 GET http://localhost/Index
warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
Failed to determine the https port for redirect.
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.ArgumentNullException: Value cannot be null.
Parameter name: uriString
at System.Uri..ctor(String uriString)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[3]
An exception was thrown attempting to execute the error handler.
System.ArgumentNullException: Value cannot be null.
Parameter name: uriString
at System.Uri..ctor(String uriString)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 449.9633ms 500
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/2.0 GET http://localhost/Error
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.ArgumentNullException: Value cannot be null.
Parameter name: uriString
at System.Uri..ctor(String uriString)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(url: "/Index") [FAIL]
[xUnit.net 00:00:02.61] System.ArgumentNullException : Value cannot be null.
[xUnit.net 00:00:02.61] Parameter name: uriString
[xUnit.net 00:00:02.61] Stack Trace:
[xUnit.net 00:00:02.61] at System.Uri..ctor(String uriString)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
[xUnit.net 00:00:02.61] at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
[xUnit.net 00:00:02.61] --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:02.61] at System.Lazy`1.CreateValue()
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.TestHost.HttpContextBuilder.<>c__DisplayClass10_0.<<SendAsync>b__0>d.MoveNext()
[xUnit.net 00:00:02.61] --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.TestHost.ClientHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Mvc.Testing.Handlers.CookieContainerHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Mvc.Testing.Handlers.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)[xUnit.net 00:00:02.63] WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(url: "/Error") [FAIL]
[xUnit.net 00:00:02.64] WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(url: "") [FAIL]
[xUnit.net 00:00:02.61] at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
[xUnit.net 00:00:02.61] D:a1sWebPortal.Int.TestsAuthenticationTests.cs(24,0): at WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(String url)
[xUnit.net 00:00:02.61] --- End of stack trace from previous location where exception was thrown ---
edit
It isn't very clear to me where/why I am getting a null reference because as far as I can tell my OpenIdConnectOptions configuration is correct (and it works with AAD SSO).
c# asp.net-core
I have an ASP.NET Core 2.2 Razor Pages Web App that I have written some integration tests for following the official guide.
I can get the tests to run locally using dotnet test or the test runners built into Visual Studio. However, on the build server (Azure DevOps Hosted 2017 agent) the tests will return a 500 error. I thought it might be related to user secrets as stated on Scott Hanselman's guide but I am still getting the same error, even after implementing some of his suggested fixes (I don't believe I need all of them) :
- Added
builder.AddUserSecrets<Startup>();to Startup. - Implemented a
CustomWebApplicationFactoryto set the environment to "Development" - code below has this as "Production" to reproduce the failure.
I also sanity checked against this guide which is more controller focused but since I only care about the response codes at this stage it serves my purpose. I have downloaded the verbose logs and they don't shed any light on the issue.
My code is below:
CustomWebApplicationFactory:
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
namespace WebPortal.Int.Tests
/// <summary>
/// Based on https://fullstackmark.com/post/20/painless-integration-testing-with-aspnet-core-web-api
/// </summary>
public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<Startup> where TStartup : class
public CustomWebApplicationFactory()
protected override void ConfigureWebHost(IWebHostBuilder builder)
builder
.ConfigureTestServices(
services =>
services.Configure(AzureADDefaults.OpenIdScheme, (System.Action<OpenIdConnectOptions>)(o =>
// CookieContainer doesn't allow cookies from other paths
o.CorrelationCookie.Path = "/";
o.NonceCookie.Path = "/";
));
)
.UseEnvironment("Production")
.UseStartup<Startup>();
AuthenticationTests:
using Microsoft.AspNetCore.Mvc.Testing;
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;
namespace WebPortal.Int.Tests
public class AuthenticationTests : IClassFixture<CustomWebApplicationFactory<Startup>>
private HttpClient _httpClient get;
public AuthenticationTests(CustomWebApplicationFactory<Startup> fixture)
WebApplicationFactoryClientOptions webAppFactoryClientOptions = new WebApplicationFactoryClientOptions
// Disallow redirect so that we can check the following: Status code is redirect and redirect url is login url
// As per https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2#test-a-secure-endpoint
AllowAutoRedirect = false
;
_httpClient = fixture.CreateClient(webAppFactoryClientOptions);
[Theory]
[InlineData("/")]
[InlineData("/Index")]
[InlineData("/Error")]
public async Task Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(string url)
// Act
HttpResponseMessage response = await _httpClient.GetAsync(url);
// Assert
try
response.EnsureSuccessStatusCode();
catch (HttpRequestException ex)
Console.WriteLine(ex.Message, ex.InnerException.Message);
Startup:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WebPortal.Authentication;
using WebPortal.Common.ConfigurationOptions;
using WebPortal.DataAccess;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.AzureAD.UI;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Http;
namespace WebPortal
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.Configure<CookiePolicyOptions>(options =>
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
);
services.AddOptions<PowerBiSettings>()
.Bind(Configuration.GetSection("PowerBI"))
.ValidateDataAnnotations()
.Validate(o => o.AreSettingsValid());
services.AddOptions<AzureActiveDirectorySettings>()
.Bind(Configuration.GetSection("AzureAd"))
.ValidateDataAnnotations()
.Validate(o => o.AreSettingsValid());
services.AddAuthentication(AzureADDefaults.AuthenticationScheme)
.AddAzureAD(options => Configuration.Bind("AzureAd", options))
.AddCookie();
services.Configure<OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
options.Authority = options.Authority + "/v2.0/";
options.TokenValidationParameters.ValidateIssuer = false;
);
services.AddTransient<Authentication.IAuthenticationHandler, AuthenticationHandler>();
services.AddTransient<IReportRepository, ReportRepository>();
services.AddHttpContextAccessor();
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddRazorPagesOptions(options =>
options.Conventions.AuthorizePage("/Reports");
);
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
var builder = new ConfigurationBuilder();
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
builder.AddUserSecrets<Startup>();
else
app.UseExceptionHandler("/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.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc();
Error output:
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.1 (64-bit .NET Core 4.6.27317.07)
[xUnit.net 00:00:01.30] Discovering: WebPortal.Int.Tests
[xUnit.net 00:00:01.40] Discovered: WebPortal.Int.Tests
[xUnit.net 00:00:01.41] Starting: WebPortal.Int.Tests
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
User profile is available. Using 'C:UsersVssAdministratorAppDataLocalASP.NETDataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[58]
Creating key dd820f09-8139-4d7d-954a-399923660f42 with creation date 2019-03-18 22:13:27Z, activation date 2019-03-18 22:13:27Z, and expiration date 2019-06-16 22:13:27Z.
info: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[39]
Writing data to file 'C:UsersVssAdministratorAppDataLocalASP.NETDataProtection-Keyskey-dd820f09-8139-4d7d-954a-399923660f42.xml'.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/2.0 GET http://localhost/Index
warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
Failed to determine the https port for redirect.
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.ArgumentNullException: Value cannot be null.
Parameter name: uriString
at System.Uri..ctor(String uriString)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[3]
An exception was thrown attempting to execute the error handler.
System.ArgumentNullException: Value cannot be null.
Parameter name: uriString
at System.Uri..ctor(String uriString)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 449.9633ms 500
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/2.0 GET http://localhost/Error
fail: Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.ArgumentNullException: Value cannot be null.
Parameter name: uriString
at System.Uri..ctor(String uriString)
at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(url: "/Index") [FAIL]
[xUnit.net 00:00:02.61] System.ArgumentNullException : Value cannot be null.
[xUnit.net 00:00:02.61] Parameter name: uriString
[xUnit.net 00:00:02.61] Stack Trace:
[xUnit.net 00:00:02.61] at System.Uri..ctor(String uriString)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AzureAD.UI.OpenIdConnectOptionsConfiguration.Configure(String name, OpenIdConnectOptions options)
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsMonitor`1.<>c__DisplayClass10_0.<Get>b__0()
[xUnit.net 00:00:02.61] at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
[xUnit.net 00:00:02.61] --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:02.61] at System.Lazy`1.CreateValue()
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
[xUnit.net 00:00:02.61] at Microsoft.Extensions.Options.OptionsMonitor`1.Get(String name)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.TestHost.HttpContextBuilder.<>c__DisplayClass10_0.<<SendAsync>b__0>d.MoveNext()
[xUnit.net 00:00:02.61] --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.TestHost.ClientHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Mvc.Testing.Handlers.CookieContainerHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
[xUnit.net 00:00:02.61] at Microsoft.AspNetCore.Mvc.Testing.Handlers.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)[xUnit.net 00:00:02.63] WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(url: "/Error") [FAIL]
[xUnit.net 00:00:02.64] WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(url: "") [FAIL]
[xUnit.net 00:00:02.61] at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
[xUnit.net 00:00:02.61] D:a1sWebPortal.Int.TestsAuthenticationTests.cs(24,0): at WebPortal.Int.Tests.AuthenticationTests.Get_PagesNotRequiringAuthenticationWithoutAuthentication_ReturnsSuccessCode(String url)
[xUnit.net 00:00:02.61] --- End of stack trace from previous location where exception was thrown ---
edit
It isn't very clear to me where/why I am getting a null reference because as far as I can tell my OpenIdConnectOptions configuration is correct (and it works with AAD SSO).
c# asp.net-core
c# asp.net-core
edited Mar 20 at 0:14
Matt Stannett
asked Mar 18 at 2:13
Matt StannettMatt Stannett
512316
512316
2
Hi, may be stupid question and you have already checked it. But have you tried to move: "builder.AddUserSecrets<Startup>();" outside of env.IsDevelopment() ?
– Nikolay
Mar 20 at 8:20
1
Seeing your stracktrace, I'm pretty sure your question is answered here
– Jesse de Wit
Mar 20 at 18:20
@Nikolay yes I have tried this thank you.
– Matt Stannett
Mar 20 at 20:28
@JessedeWit that suggestion didn't fix it my issue but it did put me onto the fact that myAzureAdconfiguration wasn't being loaded properly during the tests. Hardcoding the values in worked then I realised that I hadn't called.Build()on myConfigurationBuilderand assigned the value to the Configuration object. This also meant that I moved the code to include the secrets into theStartupconstructor.
– Matt Stannett
Mar 20 at 20:30
add a comment |
2
Hi, may be stupid question and you have already checked it. But have you tried to move: "builder.AddUserSecrets<Startup>();" outside of env.IsDevelopment() ?
– Nikolay
Mar 20 at 8:20
1
Seeing your stracktrace, I'm pretty sure your question is answered here
– Jesse de Wit
Mar 20 at 18:20
@Nikolay yes I have tried this thank you.
– Matt Stannett
Mar 20 at 20:28
@JessedeWit that suggestion didn't fix it my issue but it did put me onto the fact that myAzureAdconfiguration wasn't being loaded properly during the tests. Hardcoding the values in worked then I realised that I hadn't called.Build()on myConfigurationBuilderand assigned the value to the Configuration object. This also meant that I moved the code to include the secrets into theStartupconstructor.
– Matt Stannett
Mar 20 at 20:30
2
2
Hi, may be stupid question and you have already checked it. But have you tried to move: "builder.AddUserSecrets<Startup>();" outside of env.IsDevelopment() ?
– Nikolay
Mar 20 at 8:20
Hi, may be stupid question and you have already checked it. But have you tried to move: "builder.AddUserSecrets<Startup>();" outside of env.IsDevelopment() ?
– Nikolay
Mar 20 at 8:20
1
1
Seeing your stracktrace, I'm pretty sure your question is answered here
– Jesse de Wit
Mar 20 at 18:20
Seeing your stracktrace, I'm pretty sure your question is answered here
– Jesse de Wit
Mar 20 at 18:20
@Nikolay yes I have tried this thank you.
– Matt Stannett
Mar 20 at 20:28
@Nikolay yes I have tried this thank you.
– Matt Stannett
Mar 20 at 20:28
@JessedeWit that suggestion didn't fix it my issue but it did put me onto the fact that my
AzureAd configuration wasn't being loaded properly during the tests. Hardcoding the values in worked then I realised that I hadn't called .Build() on my ConfigurationBuilder and assigned the value to the Configuration object. This also meant that I moved the code to include the secrets into the Startup constructor.– Matt Stannett
Mar 20 at 20:30
@JessedeWit that suggestion didn't fix it my issue but it did put me onto the fact that my
AzureAd configuration wasn't being loaded properly during the tests. Hardcoding the values in worked then I realised that I hadn't called .Build() on my ConfigurationBuilder and assigned the value to the Configuration object. This also meant that I moved the code to include the secrets into the Startup constructor.– Matt Stannett
Mar 20 at 20:30
add a comment |
2 Answers
2
active
oldest
votes
It turns out that this was because I hadn't called .Build() on my ConfigurationBuilder object that I had created, AND assigned the value to the Configuration field inside the Startup class. This also meant that I moved the code to include the secrets into the Startup constructor.
Even so, my secrets were still not accessible on the build machine (makes sense because they are stored per machine). So I had to add a Command Line task to my build pipeline as well - which uses the dotnet user-secrets set command to add the secrets in that are required for the tests.
add a comment |
Is it possible that you were missing the AzureAd configuration section from you production settings file? i.e. appsettings.json vs appsettings.Development.json
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55213911%2fasp-net-core-integration-test-works-locally-but-throws-null-reference-exception%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
It turns out that this was because I hadn't called .Build() on my ConfigurationBuilder object that I had created, AND assigned the value to the Configuration field inside the Startup class. This also meant that I moved the code to include the secrets into the Startup constructor.
Even so, my secrets were still not accessible on the build machine (makes sense because they are stored per machine). So I had to add a Command Line task to my build pipeline as well - which uses the dotnet user-secrets set command to add the secrets in that are required for the tests.
add a comment |
It turns out that this was because I hadn't called .Build() on my ConfigurationBuilder object that I had created, AND assigned the value to the Configuration field inside the Startup class. This also meant that I moved the code to include the secrets into the Startup constructor.
Even so, my secrets were still not accessible on the build machine (makes sense because they are stored per machine). So I had to add a Command Line task to my build pipeline as well - which uses the dotnet user-secrets set command to add the secrets in that are required for the tests.
add a comment |
It turns out that this was because I hadn't called .Build() on my ConfigurationBuilder object that I had created, AND assigned the value to the Configuration field inside the Startup class. This also meant that I moved the code to include the secrets into the Startup constructor.
Even so, my secrets were still not accessible on the build machine (makes sense because they are stored per machine). So I had to add a Command Line task to my build pipeline as well - which uses the dotnet user-secrets set command to add the secrets in that are required for the tests.
It turns out that this was because I hadn't called .Build() on my ConfigurationBuilder object that I had created, AND assigned the value to the Configuration field inside the Startup class. This also meant that I moved the code to include the secrets into the Startup constructor.
Even so, my secrets were still not accessible on the build machine (makes sense because they are stored per machine). So I had to add a Command Line task to my build pipeline as well - which uses the dotnet user-secrets set command to add the secrets in that are required for the tests.
answered Mar 23 at 20:35
Matt StannettMatt Stannett
512316
512316
add a comment |
add a comment |
Is it possible that you were missing the AzureAd configuration section from you production settings file? i.e. appsettings.json vs appsettings.Development.json
add a comment |
Is it possible that you were missing the AzureAd configuration section from you production settings file? i.e. appsettings.json vs appsettings.Development.json
add a comment |
Is it possible that you were missing the AzureAd configuration section from you production settings file? i.e. appsettings.json vs appsettings.Development.json
Is it possible that you were missing the AzureAd configuration section from you production settings file? i.e. appsettings.json vs appsettings.Development.json
answered Mar 22 at 19:48
Jason G.Jason G.
367113
367113
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55213911%2fasp-net-core-integration-test-works-locally-but-throws-null-reference-exception%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
Hi, may be stupid question and you have already checked it. But have you tried to move: "builder.AddUserSecrets<Startup>();" outside of env.IsDevelopment() ?
– Nikolay
Mar 20 at 8:20
1
Seeing your stracktrace, I'm pretty sure your question is answered here
– Jesse de Wit
Mar 20 at 18:20
@Nikolay yes I have tried this thank you.
– Matt Stannett
Mar 20 at 20:28
@JessedeWit that suggestion didn't fix it my issue but it did put me onto the fact that my
AzureAdconfiguration wasn't being loaded properly during the tests. Hardcoding the values in worked then I realised that I hadn't called.Build()on myConfigurationBuilderand assigned the value to the Configuration object. This also meant that I moved the code to include the secrets into theStartupconstructor.– Matt Stannett
Mar 20 at 20:30