In .net Core 1 we could do this:
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
.Build();
And that gave use the Configuration object that we could then use in our console app.
All examples for .net core 2.0 seem to be tailored to the new way Asp.Net core config is created.
What is the way to create configurations for console apps?
Update: this question is not related to Asp.net core. Please do not add asp.net core tags when editing.
It seems there is no change, as Jehof says.
ConfigurationBuilder is in its own package, as Jeroen Mostert says.
But make sure you also have the Microsoft.Extensions.Configuration.Json package, where the .AddJsonFile() extension lives.
In summary, you need the following two NuGet packages:
Microsoft.Extensions.Configuration (2.0.0)
Microsoft.Extensions.Configuration.Json (2.0.0)
Store a private static IServiceProvider provider; in your Program.cs. Then Setup the configuration just like you would in aps.net core but of course you would do it in Main(). Then Configure each section inside your IServiceProvider. This way you can use the constructor dependency injection. Also note that I have two configurations in my watered down example. One contains secrets that should be kept out of source control and stored outside of the project structure, and I have AppSettings which contains standard configuration settings that don't need to be kept private.(It is important!)
When you want to use the config then you can take it out of the provider, or pull an object out of the provider that uses your settings classes in their constructors.
private static IServiceProvider provider;
private static EventReceiver receiver;
static void Main(string[] args)
{
IConfigurationRoot config = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(path: "/opt/Secrets.json", optional: false, reloadOnChange: true)
.AddJsonFile(path: "AppSettings.json", optional: false, reloadOnChange: true)
.Build();
provider = new ServiceCollection()
.AddSingleton<CancellationTokenSource>()
.Configure<Settings>(config.GetSection("SettingsSection"))
.BuildServiceProvider();
receiver = new EventReceiver<Poco>(ProcessPoco);
provider.GetRequiredService<CancellationTokenSource>().Token.WaitHandle.WaitOne();
}
private static void ProcessPoco(Poco poco)
{
IOptionsSnapshot<Settings> settings = provider.GetRequiredService<IOptionsSnapshot<Settings>>();
Console.WriteLine(settings.ToString());
}
these are the dependencies I recommend starting out with when making a dotnetcore cli app.
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.0.0" />
<PackageReference Include="microsoft.extensions.logging.abstractions" Version="2.0.0" />
Also note that you will need to copy your settings to your publish and build directories. You can do that by adding targets to your csproj file.
<Target Name="CopyToOut" BeforeTargets="BeforeBuild">
<Copy SourceFiles="../ProjPath/AppSettings.json" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" />
</Target>
<Target Name="CopyToOutOnPublish" AfterTargets="Publish">DestinationFolder="$(PublishDir)" SkipUnchangedFiles="true" />
<Copy SourceFiles="../ProjPath/AppSettings.json" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="true" />
</Target>
Related
Slowly migrating system up from .net core 2.1 to 3.1.
While updating IdentityServer4 to 3.1 version.
I've stucked into problem method AddIdentityServer where options are specified..
var builder = services.AddIdentityServer(options =>
{
(!string.IsNullOrWhiteSpace(identityServerSettingsConfig.PublicOrigin))
{
options.PublicOrigin = identityServerSettingsConfig.PublicOrigin;
}
})
Error: 'IdentityServerOptions' does not contain a definition for 'PublicOrigin' and no accessible extension method 'PublicOrigin' accepting a first argument of type 'IdentityServerOptions' could be found
Installed packages:
<PackageReference Include="IdentityServer4" Version="4.1.2" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="4.1.2" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="2.5.3" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.0">
The IdentityServerOptions.PublicOrigin property was removed in IdentityServer4 1.0 back in 2016.
This GitHub issue is asking the same question as yourself: https://github.com/IdentityServer/IdentityServer4/issues/4535
One of IdentityServer's authors said it was removed and explained why - and how you can work-around it (assuming you actually need it, I mention this because you probably don't need to restore this functionality):
leastprivilege commented on 19 Jun 2020:
It's gone. It was a hack - please use the forwarded headers approach in ASP.NET Core from now on.
The workaround is to add a middleware step that calls HttpContextExtensions.SetIdentityServerOrigin at the beginning of your pipeline, so it should look something like this:
In the code-block below, add the code between the //------- comments.
I included other Configure pipeline/appBuilder methods from one of my own IS4 projects so you can see a complete example.
using IdentityServer4.Extensions; // For IS4's `HttpContextExtensions`
public class Startup
{
// ...
public void Configure( IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime applicationLifetime )
{
_ = app
//-------------------------------- Add the code below this line
.Use( async (ctx, next) =>
{
ctx.SetIdentityServerOrigin( "https://example.com" );
await next();
})
//-------------------------------- Add the code above this line
.UseCors()
.UseAuthentication()
.UseOpenApi()
.UseSwaggerUi3()
.UseIdentityServer()
.UseRouting()
.UseAuthorization()
.UseEndpoints( routeBuilder =>
{
_ = routeBuilder.MapControllers();
} )
.UseStaticFiles();
}
}
My csproject file is indicating: <TargetFramework>netcoreapp3.0</TargetFramework>
In my startup im using the followinhg:
services.AddMvc(x => x.Filters.AddService<TransactionFilter>())
.AddJsonOptions(options => options.JsonSerializerOptions... )
But, ReferenceLoopHandling is not available inside options.JsonSerializerOptions.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentNHibernate" Version="2.1.2" />
<PackageReference Include="FullContact.Contacts.API" Version="1.0.3" />
<PackageReference Include="Google.Cloud.Storage.V1" Version="2.3.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Cors" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="5.5.0" />
<PackageReference Include="MySql.Data" Version="8.0.17" />
<PackageReference Include="piplclient" Version="5.0.9" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="5.5.0" />
</ItemGroup>
</Project>
As part of the work to improve the ASP.NET Core shared framework, Json.NET has been removed from the ASP.NET Core shared framework. Your app may require this reference if it uses Newtonsoft.Json-specific feature such as JsonPatch or converters or if it formats Newtonsoft.Json-specific types.
To use Json.NET in an ASP.NET Core 3.0 project:
Add a package reference to Microsoft.AspNetCore.Mvc.NewtonsoftJson.
Update Startup.ConfigureServices to call AddNewtonsoftJson.
services.AddMvc()
.AddNewtonsoftJson();
This sets up MVC and configures it to use Json.NET instead of that new API. And that AddNewtonsoftJson method has an overload that allows you to configure the Json.NET options like you were used to with AddJsonOptions in ASP.NET Core 2.x.
services.AddMvc()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings = new JsonSerializerSettings() { … };
});
Reference:
https://learn.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-2.2&tabs=visual-studio#jsonnet-support
https://stackoverflow.com/a/55666898/10201850
As of March 2020, the default JSON serializer does not support reference loop handling.
In order to handle that issue, you'll have to first install the older JSON serializer (used in older versions of .NET Core), Microsoft.AspNetCore.Mvc.NewtonsoftJson in the Nuget package manager.
The usage is pretty simple:
services.AddMvc().AddNewtonsoftJson(o =>
{
o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
Or like this if you are using a simple web API:
services.AddControllers().AddNewtonsoftJson(o =>
{
o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
As mentioned above you need to install Microsoft.AspNetCore.Mvc.NewtonsoftJson, Microsoft.AspNetCore.SignalR.Protocols.Newtonsoft packages and configure with AddNewtonsoftJsonProtocol in order to still use Newtonsoft instead of System.Text.Json (ReferenceLoopHandling not available yet)
For SignalR it would be
services.AddSignalR().AddNewtonsoftJsonProtocol(p =>
{
p.PayloadSerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
Add a package Microsoft.AspNetCore.Mvc.NewtonsoftJson
version - 3.1.3
services.AddMvc().AddNewtonsoftJson(options => options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);
MvcNewtonsoftJsonOptions
services.PostConfigure<MvcNewtonsoftJsonOptions>(o =>
{
o.SerializerSettings.ContractResolver = new MyCustomContractResolver()
{
NamingStrategy = new CamelCaseNamingStrategy()
};
o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
I am totaly new with databases but this project needs one otherwise it wont work. So i need a SQLite Database. I installed ever NuGet needed and implemented my Database table with the rows and connected the Database with my project.
This is my class
public class DatenbankDaten
{
public string zsw_id { get; set; }
public int personio_id { get; set; }
public string von { get; set; }
public string bis { get; set; }
}
This is the Code
private static string LoadConnectionString( string id = "Default")
{
return ConfigurationManager.ConnectionStrings[id].ConnectionString;
}
public void SaveIds ( DatenbankDaten daten)
{
using (IDbConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
cnn.Execute("insert into Ids (zsw_id,personio_id,von,bis) values (#zsw_id, #personio_id, #von, #bis", daten);
}
}
And i get a NullReference exception back.. I mean i understand it because i dont have written the connectionstring where it belongs too. At the moment the connectionstring is in my .csproj
<ItemGroup>
<Content Include="zausinger.db">
<connectionStrings>
<add name="Default" connectionString="Data Source=.\zausinger.db;Version=3;" providerName="System.Data.SqlClient"/>
</connectionStrings>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
> and these are my PackageReferences
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.123" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.115.5" />
<PackageReference Include="System.ServiceModel.Duplex" Version="4.8.*" />
<PackageReference Include="System.ServiceModel.Federation" Version="4.8.*" />
<PackageReference Include="System.ServiceModel.Http" Version="4.8.*" />
<PackageReference Include="System.ServiceModel.NetTcp" Version="4.8.*" />
<PackageReference Include="System.ServiceModel.Security" Version="4.8.*" />
<PackageReference Include="Telegram.Bot" Version="17.0.0" />
</ItemGroup>
if someone could help a newbie i would i appriciate it.
.NET 6 is .NET Core 6 and no longer uses app.config and the related classes.
Remove the obsolete packages and use the new configuration middleware. Settings are read from multiple sources now, with appsettings.json just one of the default sources.
The current Microsoft Sqlite driver is Microsoft.Data.Sqlite. The current version is 6.0.5
Using the Generic Host package you can add Configuration, Logging and DI middleware to your application in a single line.
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Data.Sqlite;
using Dapper;
using IHost host = Host.CreateDefaultBuilder(args).Build();
The default configuration sources are described in the documentation and include JSON config files, environment variables and command line arguments.
After that you can retrieve configuration settings by their key. Connection strings get their own method :
var Configuration = host.Services.GetRequiredService<IConfiguration>();
var cns = Configuration.GetConnectionString("Default");
using var connection = new SqliteConnection("Data Source=hello.db");
var rows = await connection.QueryAsync("select * from Test");
Console.WriteLine($"Rows {rows.Count()}");
The application's settings are stored in the appsettings.json file :
{
"ConnectionStrings": {
"Default": "./mydb.db"
}
}
Finally, the csproj file adds Microsoft.Data.SqlClient and Microsoft.Extensions.Hosting which in turn adds Configuration, Logging and Dependency Injection as dependencies :
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.0.123" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.5" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
</ItemGroup>
</Project>
You can use only the Configuration middleware if you want, and add only the sources you need :
IConfiguration Configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.AddEnvironmentVariables()
.AddCommandLine(args)
.Build();
The Azure Function's .csproj definition is per the following snippet:
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<LangVersion>10.0</LangVersion>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<_FunctionsSkipCleanOutput>true</_FunctionsSkipCleanOutput>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.1.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.0.1" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.6.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.3.0" OutputItemType="Analyzer" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Timer" Version="4.1.0" />
</ItemGroup>
The Program.cs file's initialization is like the following code snippet:
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureAppConfiguration((context, configure) =>
{
configure
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();
})
.ConfigureServices((context, services) =>
{
services.AddMyServices();
})
.Build();
The compiler issues the following error message:
Severity Code Description Project File Line Suppression State
Error MSB4062 The "GenerateFunctionMetadata" task could not be loaded from the assembly C:\Users\myusername.nuget\packages\microsoft.net.sdk.functions\4.0.1\build..\tools\net6.0\Microsoft.NET.Sdk.Functions.MSBuild.dll. Confirm that the declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask. MyApp.Functions C:\Users\myusername.nuget\packages\microsoft.azure.functions.worker.sdk\1.3.0\build\Microsoft.Azure.Functions.Worker.Sdk.targets 60
Would you please give a direction on fixing this problem?
We need to remove Microsoft.NET.Sdk.Functions NuGet package reference to address this compile issue.
Setting up an Azure Function that references other netstandard projects which on their turn reference Microsoft.Extensions.Logging.
When the Function runs locally without any references to the other projects, everything starts fine. But as soon as I add a reference to one of the other projects, I get the following exception at startup:
TestTrigger: Microsoft.Azure.WebJobs.Host: Error indexing method 'TestTrigger'. Microsoft.Azure.WebJobs.Host: Cannot bind parameter 'log' to type ILogger. Make sure the parameter Type is supported by the binding. If you're using binding extensions (e.g. Azure Storage, ServiceBus, Timers, etc.) make sure you've called the registration method for the extension(s) in your startup code (e.g. builder.AddAzureStorage(), builder.AddServiceBus(), builder.AddTimers(), etc.).
This is the initial code I have for my Timer function
public class TestTrigger
{
private ITester _tester;
public TestTrigger(ITester tester)
{
_tester = tester;
}
[FunctionName("TestTrigger")]
public void Run([TimerTrigger("* * * * * *")] TimerInfo myTimer, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.UtcNow}");
_tester?.TestMethod().Wait();
}
}
I have my dependencies injected in the following Startup class
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
var cfgBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile($"appsettings.json", true, true)
.AddJsonFile($"appsettings.dev.json", true, true)
.AddEnvironmentVariables();
var configuration = cfgBuilder.Build();
builder.Services
.AddSingleton<ITester, Tester>()
.AddLogging()
.AddOptions();
}
}
The custom class that implements ITester is part of a netstandard 2.0 project that references the Microsoft.Extensions.Logging.Abstractions 3.0.0.0 nuget package. The functions project itself is a netcoreapp2.1 project that also references that same nuget package, as well as the Microsoft.NET.Sdk.Functions 1.0.29, the Microsoft.Azure.Functions.Extensions 1.0.0 and the Microsoft.NETCore.App 2.1.0 package.
For reference, the csproj files:
The function project
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<AzureFunctionsVersion></AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Extensions" Version="1.0.0" />
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.29" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TestLibrary\TestLibrary.csproj" />
</ItemGroup>
</Project>
The referenced project:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.0.0" />
</ItemGroup>
</Project>
I am quite sure it's reference issue, but cannot put my hands on it.
Any help?
Have reproduced your error:
Seems the error comes from the reference project.
Solution:
Downgrading the version of Microsoft.Extensions.Logging.Abstractions to 2.2.0.
Cause:
The binding engine doesn't recognize your parameter's type as being the same since they're from different assemblies.