How to override default ports in Kestrel - c#

i have simple method
public static IHostBuilder CreateHostBuilder(string[] args)
{
return Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(builder => builder.UseStartup<Startup>());
}
and i am write appsettings:
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http1AndHttp2"
},
"Endpoints": {
"Api": {
"Url": "https://+:5005",
"Protocols": "Http1AndHttp2"
},
"Grpc": {
"Url": "http://+:5006",
"Protocols": "Http2"
}
}
}
but when i start app, i see warning:
"Microsoft.AspNetCore.Server.Kestrel", "message": "Overriding address(es) 'https:\/\/localhost:5000, https:\/\/localhost:5001'. Binding to endpoints defined in UseKestrel() instead.", "addresses": "https:\/\/localhost:5000, https:\/\/localhost:5001
", "methodName": "UseKestrel()" }
and app start at standard port 5000, but i expect on port 5005
Why Kestrel changes the start port and how to make the application start on a given https://localhost:5005/api-docs/someService (i am use swagger)

As said on your application startup just do it in UseKestrel()
return Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(builder => builder.UseKestrel(x=>x.Listen(IPAddress.Any, 5005)).UseStartup<Startup>());

i am find that i need feel launchSettings.json with
"launchUrl": "https://localhost:5005/api-docs/SomeService"

Related

.NET Core 6 Console App hosted service not starting as Windows Service?

I got a .NET 6.0 Core Console Application that starts a service and log some data with Serilog which works good. But after installing it as a Windows Service and hitting start the services seems to start but I get no log data anymore? What am I missing?
Start up :
public static async Task Main(string[] args)
{
Log.Logger = new LoggerConfiguration().DefaultLoggerSetup<Program>();
var microsoftLogger = new SerilogLoggerFactory(Log.Logger).CreateLogger<IProgram>();
var serviceName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
Log.Information("Starting {serviceName} version {version}.", serviceName, System.Reflection.Assembly.GetExecutingAssembly().GetName().Version?.ToString());
Log.Information("{#serviceName} microservice loading MySettings.json.", serviceName);
var configurationBuilder = new ConfigurationBuilder().AddJsonFile("MySettings.json").Build();
var MySettings = configurationBuilder.Get<MySettings>();
Log.Information("{#serviceName} microservice loading appsettings.json.", serviceName);
configurationBuilder = new ConfigurationBuilder().AddJsonFile("appSettings.json").Build();
var appSettings = configurationBuilder.Get<AppSettings>();
var sqlConnectionString = appSettings.ConnectionString;
Log.Information("{#serviceName} building and starting.", serviceName);
CreateHostBuilder(args, configurationBuilder, appSettings, MySettings, sqlConnectionString).Build().Run();
Log.Information("{#serviceName} microservice Built and stated.", serviceName);
}
Method to build the host :
public static IHostBuilder CreateHostBuilder(string[] args,
IConfiguration configurationBuilder,
AppSettings appSettings,
MySettings mySettings,
string sqlConnectionString) =>
Host.CreateDefaultBuilder(args)
.UseCloudMQ(context => context.UseSettings(appSettings.MQSettings))
.UseSerilog((context, services, configuration) => configuration
.ReadFrom.Configuration(context.Configuration)
.ReadFrom.Services(services)
.Enrich.FromLogContext())
.UseWindowsService()
.ConfigureServices((hostContext, services) =>
{
services
.AddTransient<ConnectorConfig>(s => appSettings.ConnectorConfig)
.AddTransient<IMyService, MyService>()
.AddTransient<IMyController, MyController>()
.AddTransient<IMySettings>(s => MySettings)
.AddTransient<IMyService, MyService>()
.AddSingleton<IInputOuputLogger>(new InputOuputLogger(configurationBuilder))
.AddDbContext<AppDbContext>(options => options.UseSqlServer(sqlConnectionString, opt => opt.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery)))
.AddHostedService<MyService>();
});
Simple hosted service :
public class MyService : IHostedService, IMyAnestesiService
{
private readonly ILogger<MyService> _logger;
public MyService(ILogger<MyService> logger)
{
_logger = logger;
_logger.LogInformation("{#serviceName} microservice started.", GetType().Name);
}
public Task StartAsync(CancellationToken cancellationToken)
{
return Task.FromResult(true);
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.FromResult(true);
}
public void Run()
{
_logger.LogInformation("MyService started.");
}
}
Edit : When running the service in CMD the log in displayed in the CMD but its also saved to file with this :
"serilog": {
"Using": [
"Serilog",
"Serilog.Sinks.File",
"Serilog.Sinks.Console"
],
"MinimumLevel": {
"Default": "Verbose",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId" ],
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss.fff} [{Level}] {SourceContext} {Message}{NewLine}{Exception}",
"theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console"
}
},
{
"Name": "File",
"Args": {
"path": "C:\\DEVSTUFF\\log.txt",
"outputTemplate": "{Timestamp:G} {SourceContext} [{Level}] {Message}{NewLine:1}{Exception:1}",
"formatter": "Serilog.Formatting.Json.JsonFormatter, Serilog",
"fileSizeLimitBytes": 1000000,
"rollOnFileSizeLimit": "true",
"shared": "true",
"flushToDiskInterval": 3
}
}
]
}
So even if I can´t see the log in the CMD while running it as a Windows Services I should at least get log rows in file like before.
Where are you writing logs in the Windows Service scenario?
For the console application, it can write logs to the Terminal which is not possible for the windows service scenarios. You need to write somewhere like a file, or database.
You can have a look at this link

Serilog not writing to file

Setting up Serilog for my .net core app, everything compiles and runs but not writing to the file. How can I pinpoint the problem?
I am only use Serilog package - but there seems to be a multitude of others, and I'd be happy to use another one.
In my startup.cs I have
using Serilog;
public Startup(IConfiguration configuration)
{
Configuration = configuration;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.ReadFrom.Configuration(configuration)
.CreateLogger();
}
in my appsettings.json I have
{
"AllowedHosts": "*",
"Serilog": {
"MinimumLevel": "Debug",
"Override": {
"Microsoft.AspNetCore": "Warning"
},
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "File",
"Args": {
"path": "C:\\log\\Batching\\apptest.log"
}
}
]
}
}
in my Program.cs I have
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
And finally I use this statement to test the writing:
Log.Information("write something to file");
It is not working. What can I try next?
Just as mentioned in the document:
To use the file sink with Microsoft.Extensions.Configuration, for example with ASP.NET Core or .NET Core, use the Serilog.Settings.Configuration package
And you could find introduction to different packages in this page:
https://github.com/serilog
I tried with the packages:
Set as below in program.cs:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseSerilog((context, configuration) =>
{
var config = context.Configuration;
configuration.ReadFrom.Configuration(config);
});
It works well in my case:
Update:
I configured as below in appsettings.json:
I also tried with the absolute path of my desktop, it worked either

Integrating Ocelot 16.0 with ASP.Net Core 3.1 not working as I need to use Swagger with Ocelot

I have used Ocelot with Asp.Net Core 2.1 and its working but when using with Asp.Net Core 3.1 it is not working at all. In my opinion, it is not picking up the "ocelot.json" file. Following is my Program.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace ApiGateway
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
config
.SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddJsonFile($"ocelot.{hostingContext.HostingEnvironment.EnvironmentName}.json")
.AddEnvironmentVariables();
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
And below is Startup.cs file :
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
namespace ApiGateway
{
public class Startup
{
private IConfiguration configuration;
public Startup(IConfiguration configuration)
{
this.configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot(configuration);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", async context => {
await context.Response.WriteAsync("API GATEWAY FUNCIONANDO");
});
});
app.UseOcelot().Wait();
}
}
}
Below is ocelot.Development.json file :
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/TestApi/api/test",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": "80"
}
],
"UpstreamPathTemplate": "/getTest"
},
{
"DownstreamPathTemplate": "/TestMicroS/api/values",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": "82"
}
],
"UpstreamPathTemplate": "/getValues"
}
],
"GlobalConfiguration": {
}
}
I have referred all above configuration from YouTube but it is not working. Local website is working but when I try to hit the UpStream path it is giving me localhost not found 404 error. Please assist me to resolve this.
Thanks in advance.
Try renaming ReRoutes to Routes in your JSON file.
I had similar issue recently,
apart from the ReRoutes to Routes , I had another problem in
In the ocelote.json file
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 7083
}
The port number which I had configured was for https and not for http in launchsettings.json file of the project
"applicationUrl": "https://localhost:7083",
I changed it to https to make it work
"DownstreamScheme": "https",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 7083
}

How to overwrite application name specified in appsettings.json when using Serilog?

My appsettings.json looks like this:
{
"Serilog": {
"Using": [ "Serilog.Sinks.File" ],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "%APPDATA%\\FancyProject\\logs\\RR.log",
"formatter": "Serilog.Formatting.Json.JsonFormatter",
"rollingInterval": "Day",
"retainedFileCountLimit": 20,
"buffered": false
}
}
],
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId", "WithExceptionDetails" ],
"Properties": {
"Application": "SampleName"
}
}
}
Loading the settings:
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
I'd like to use the same config file for multiple projects in my solution but with a different application name in order to distinguish between services.
Is there a way to change the application name ("SampleName" in my config) in code when loading the config?
You can use the following extension method for IConfiguration interface to update the configuration instance after reading it from appsettings.json
public static class Ext
{
public static IConfiguration ApplyAppName(this IConfiguration configuration, string appName)
{
foreach (var (key, _) in configuration.AsEnumerable())
if (key.StartsWith("Serilog") && key.EndsWith("Application"))
configuration[key] = appName;
return configuration;
}
}
And use it in following way (based on
serilog-settings-configuration sample from GitHub) before configuring and creating a logger
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build()
.ApplyAppName("MyApp");
var logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
Alternatively, you can follow Serilog integration for ASP.NET Core 2+ and use UseSerilog() method with the above ApplyAppName extension during CreateHostBuilder call
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); })
.UseSerilog((hostingContext, loggerConfiguration) =>
{
var config = hostingContext.Configuration.ApplyAppName("MyApp");
loggerConfiguration.ReadFrom.Configuration(config);
});
I solved it by removing the Properties section from the config and load it this way:
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.Enrich.WithProperty("ApplicationName", "my application")
.CreateLogger();
PavelAnikhouski's (deleted) answer was actually the correct answer to my question but I think directly adding the correct application name is cleaner than modifying a placeholder.

How to configure SSL in kestrel self-host web application in linux and mac and Register certificate to SSL port [duplicate]

TL;DR What is today the correct way to setup HTTPS with ASP.NET Core 2.0?
I would like to configure my project to use https and a certificate like they have shown at BUILD 2017. I have tried several settings but nothing worked. After some research, I am even more confused. It seems that there are many ways to configure URLs and ports… I have seen appsettings.json, hosting.json, via code, and in launchsettings.json we can also set the URL and port.
Is there a "standard" way to do it?
Here is my appsettings.development.json
{
"Kestrel": {
"Endpoints": {
"Localhost": {
"Address": "127.0.0.1",
"Port": "40000"
},
"LocalhostWithHttps": {
"Address": "127.0.0.1",
"Port": "40001",
"Certificate": {
"HTTPS": {
"Source": "Store",
"StoreLocation": "LocalMachine",
"StoreName": "My",
"Subject": "CN=localhost",
"AllowInvalid": true
}
}
}
}
}
}
But it always takes the url and the port from launchsettings.json when I start from the command line with dotnet run or when I start with the debugger from Visual Studio.
This is my Program.cs and Startup.cs
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
public class Startup
{
public IConfiguration Configuration { get; }
public string Authority { get; set; } = "Authority";
public string ClientId { get; set; } = "ClientId";
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.Configure<MvcOptions>(options => options.Filters.Add(new RequireHttpsAttribute()));
JsonConvert.DefaultSettings = () => new JsonSerializerSettings() {
NullValueHandling = NullValueHandling.Ignore
};
services.AddSingleton<IRepository, AzureSqlRepository>(x => new AzureSqlRepository(Configuration.GetConnectionString("DefaultConnection")));
services.AddSingleton<ISearchSplitService, SearchSplitService>();
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options => new JwtBearerOptions {
Authority = this.Authority,
Audience = this.ClientId
});
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions() { HotModuleReplacement = true, ReactHotModuleReplacement = true, HotModuleReplacementEndpoint = "/dist/__webpack_hmr" });
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(routes => {
routes.MapRoute(
name: "default",
template: "{controller=Home}/{id?}");
routes.MapSpaFallbackRoute(
name: "spa-fallback",
defaults: new { controller = "Home", action = "Index" });
});
}
}
As I have said, I was not able to get it working in any constallation. What is today the correct way to setup HTTPS with ASP.NET Core 2.0?
Unfortunately, the way of configuration-based way of setting up HTTPS that has been shown in various videos or tutorials before the launch of ASP.NET Core 2.0 didn’t make it into the final release.
For 2.0, the only way to configure HTTPS is in code, by explicitly setting up the Kestrel listeners, as explained in this announcement, and using ListenOptions.UseHttps to enable HTTPS:
var host = new WebHostBuilder()
.UseKestrel(options =>
{
options.ListenAnyIP(443, listenOptions =>
{
listenOptions.UseHttps("server.pfx", "password");
});
})
.UseStartup<Startup>()
.Build();
Unfortunately, at the time of release, the official documentation also did not cover this properly and advertised the configuration-based way that wasn’t implemented. This has been fixed since.
Starting with ASP.NET Core 2.1, configuration based HTTPS setup will be possible, as originally promised. This will likely look like this, as explained by Tratcher on GitHub:
"Kestrel": {
"Endpoints": {
"HTTPS": {
"Url": "https://*:443",
"Certificate": {
"Path": "server.pfx",
"Password": "password"
}
}
}
}
In your particular example, the code-based configuration would look like the following. Note that if you don’t want to use a certificate file, you need to manually retrieve the certificate from the certificate store first.
.UseKestrel(options =>
{
// listen for HTTP
options.ListenLocalhost(40000);
// retrieve certificate from store
using (var store = new X509Store(StoreName.My))
{
store.Open(OpenFlags.ReadOnly);
var certs = store.Certificates.Find(X509FindType.FindBySubjectName,
"localhost", false);
if (certs.Count > 0)
{
var certificate = certs[0];
// listen for HTTPS
options.ListenLocalhost(40001, listenOptions =>
{
listenOptions.UseHttps(certificate);
});
}
}
})

Categories