C
C#2mo ago
Esa

Need help debugging a tiny console app on server

Halp. I'm losing my mind rapidly. Scenario: I'm writing a tcp client tester to PoC something, and I've written it as a tiny console application where I use dependency injection to see that that aspect also works.
services.AddOptions<SysConfig>()
.Configure<IConfiguration>((options, configuration) => configuration.Bind(SysConfig.SectionName, options))
.Validate(options => options.Port is not default(int), $"{nameof(SysConfig.Port)} is not defined!")
services.AddOptions<SysConfig>()
.Configure<IConfiguration>((options, configuration) => configuration.Bind(SysConfig.SectionName, options))
.Validate(options => options.Port is not default(int), $"{nameof(SysConfig.Port)} is not defined!")
This is how I normally do it. However... When I run this exe on the target server, it fails on the Validation step. It says the values are default. And this is where it gets weird. If I replace that neat configuration oneliner with an explicit behemoth that manually gets the required section, retrieves the string and binds it to the property - then it works:
.Configure<IConfiguration>((options, configuration) =>
{
IConfigurationSection sysSection = configuration.GetRequiredSection("Sys");
if (!sysSection.Exists()) throw new Exception("Missing section \"Sys\" in configuration!");

var portAsString = sysSection.GetValue<string>("Port");

options.Port = int.Parse(portAsString!);
})
.Configure<IConfiguration>((options, configuration) =>
{
IConfigurationSection sysSection = configuration.GetRequiredSection("Sys");
if (!sysSection.Exists()) throw new Exception("Missing section \"Sys\" in configuration!");

var portAsString = sysSection.GetValue<string>("Port");

options.Port = int.Parse(portAsString!);
})
But attempting to oneline it causes the error where everything is default, and thus failing validation. This only happens on the target server which has a .net 8.0 x64 runtime installed, whereas I have a .net 8.0 x64 SDK installed on my dev environment. Does this make sense to anyone? I don't really know where to start looking, apart from installing an SDK on the server to see - but that sounds very wrong lol.
16 Replies
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
Esa
Esa2mo ago
Oh neat, wasn't aware of that shorthand thanks
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
Esa
Esa2mo ago
So I'm using a JSON which is like this:
{
"Sys":{
"Port":123
}
}
{
"Sys":{
"Port":123
}
}
Which corresponds to the options record:
public record SysConfig
{
public const string SectionName = "Sys";

public required int Port { set; get; }
};
public record SysConfig
{
public const string SectionName = "Sys";

public required int Port { set; get; }
};
Which is accessed like this:
var hostbuilder = new HostBuilder();
hostBuilder.ConfigureHostConfiguration(configurationBuilder => configurationBuilder.AddJsonFile(path));

hostBuilder.ConfigureServices(services =>
services.AddOptions<SysConfig>()
// this oneliner fails on server
.Configure<IConfiguration>((options, configuration) => configuration.Bind(NceConfig.SectionName, options))
// this block works on server
/*.Configure<IConfiguration>((options, configuration) =>
{
IConfigurationSection sysSection = configuration.GetRequiredSection("Sys");
if (!sysSection.Exists()) throw new Exception("Missing section \"Sys\" in configuration!");

var portAsString = sysSection.GetValue<string>("Port");

options.Port = int.Parse(portAsString!);
})*/
.Validate // blabla validation
();
var hostbuilder = new HostBuilder();
hostBuilder.ConfigureHostConfiguration(configurationBuilder => configurationBuilder.AddJsonFile(path));

hostBuilder.ConfigureServices(services =>
services.AddOptions<SysConfig>()
// this oneliner fails on server
.Configure<IConfiguration>((options, configuration) => configuration.Bind(NceConfig.SectionName, options))
// this block works on server
/*.Configure<IConfiguration>((options, configuration) =>
{
IConfigurationSection sysSection = configuration.GetRequiredSection("Sys");
if (!sysSection.Exists()) throw new Exception("Missing section \"Sys\" in configuration!");

var portAsString = sysSection.GetValue<string>("Port");

options.Port = int.Parse(portAsString!);
})*/
.Validate // blabla validation
();
So it doesn't say that the section is missing, but rather that the values bound are 0
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
Esa
Esa2mo ago
yea that just tells me that the json probably doesn't contain a valid port
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
Esa
Esa2mo ago
Eh startup i guess, it should only be read once this is a system integration so the values are rather fixed
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
Esa
Esa2mo ago
Ah okay, gotcha. In that case it sounds correct with a singleton as it's currently
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
Esa
Esa2mo ago
(I've abstracted some of the above into methods)
var builder = new HostBuilder();
string pathToSecretsJson = GetPathToEnvironmentJson();
ConfigureHost(builder, pathToSecretsJson);

IHost host = BuildHost(builder);

Console.WriteLine("Host built!");
SysConfig sysConfig = host.Services.GetService<IOptions<SysConfig>>()!.Value;
var builder = new HostBuilder();
string pathToSecretsJson = GetPathToEnvironmentJson();
ConfigureHost(builder, pathToSecretsJson);

IHost host = BuildHost(builder);

Console.WriteLine("Host built!");
SysConfig sysConfig = host.Services.GetService<IOptions<SysConfig>>()!.Value;
this is where all of that happens then So I don't get why this works on one machine but fails on the other both machines can find the json and i've confirmed the values are read (the configuration provider has them in both environments)
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
Esa
Esa2mo ago
Hm I don't get what you meant here. Where does BindConfiguration get its arguments from? .Configure takes a delegate, but your BindConfiguration does not
Unknown User
Unknown User2mo ago
Message Not Public
Sign In & Join Server To View
Esa
Esa2mo ago
Wonderful, thanks!