Request URL error in Swagger for Ocelot like http://http:// - .net-core

I'm using Swagger for Ocelot in .Net microservice gateway. I'm using the following package for ocelot swagger:
Install-Package MMLib.SwaggerForOcelot -Version 1.10.1
I'm getting this following issue.
As I mentioned in the image, the http is replicating in the gateway request URL
My project config is following,
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<UserSecretsId>38efa0b7-845b-41f3-914c-1bfc80defa9b</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>..\..\..\..</DockerfileContext>
<DockerComposeProjectPath>..\..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.9.10" />
<PackageReference Include="MMLib.SwaggerForOcelot" Version="1.10.0" />
<PackageReference Include="Ocelot" Version="13.8.0" />
</ItemGroup>
</Project>
My Ocelot configuration is following,
{
"ReRoutes": [
{
"DownstreamPathTemplate": "/{everything}",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "customer.api",
"Port": 80
}
],
"UpstreamPathTemplate": "/api/Customer/{everything}",
"UpstreamHttpMethod": [ "POST", "PUT", "GET", "DELETE", "PATCH" ],
"SwaggerKey": "skCustomer"
}
],
"SwaggerEndPoints": [
{
"Key": "skCustomer",
"Config": [
{
"Name": "Customer API",
"Version": "v1",
"Url": "http://customer.api:80/CustomerAPI/Customer/swagger.json"
}
]
}
],
"GlobalConfiguration": {
"RequestIdKey": "OcRequestId",
"AdministrationPath": "/administration"
}
}
My swagger config in startup file is following,
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerForOcelot(_cfg);
services.AddOcelot(_cfg);
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public async void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// 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.UseSwaggerForOcelotUI(_cfg, opt =>
{
opt.EndPointBasePath = "/swagger/docs";
});
await app.UseOcelot();
}

It looks like issue The scheme is duplicated.
Unfortunately it is still not fixed.
As a workaround you can downgrade to version 1.8

Related

Update to .NET6, Serilog 2.12 and Sinks.ApplicationInsights 4.0.0

I have updated a worker service application to .NET6 from .NET Core 3.1, and also updated Serilog and the Application Insights sink to the latest versions.
I noticed that even though I this entry on the configuration, I don't see the application name on App Insights, it is always blank. This used to work with the previous version
"WriteTo": [
{
"Name": "ApplicationInsights",
"Args": {
"restrictedToMinimumLevel": "Information",
"telemetryConverter": "Serilog.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights",
"InstrumentationKey": "<Key>"
}
}
],
"Enrich": [ "FromLogContext" ],
"Properties": {
"Application": "ApplicationName"
}
Any idea how I get this to work again?
Thank you,
Check the below steps to get the ApplicationName on App Insights for .NET 6 Application.
Updated the Serilog.AspNetCore and Sinks.ApplicationInsights packages to the latest version.
Add .Enrich.FromLogContext() and
.Enrich.WithProperty("ApplicationName", appname) in Program.cs file.
My appsettings.json file :
{
"Logging": {
"ApplicationInsights": {
"LogLevel": {
"Default": "Debug",
"Microsoft": "Error"
}
},
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ApplicationInsights": {
"ConnectionString": "InstrumentationKey=*****;IngestionEndpoint=https://****.in.applicationinsights.azure.com/;LiveEndpoint=https://****.livediagnostics.monitor.azure.com/"
},
"WriteTo": [
{
"Name": "ApplicationInsights",
"Args": {
"restrictedToMinimumLevel": "Information",
"telemetryConverter": "Serilog.Sinks.ApplicationInsights.TelemetryConverters.TraceTelemetryConverter, Serilog.Sinks.ApplicationInsights",
"InstrumentationKey": "Copy the Instrumentation Key"
}
}
],
"Enrich": [ "FromLogContext" ],
"Properties": {
"Application": "Serilog Application Insights"
}
}
My Program.cs file :
using Serilog;
using Serilog.Sinks.ApplicationInsights.TelemetryConverters;
using System.ComponentModel;
using static System.Net.Mime.MediaTypeNames;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
var appname = builder.Configuration.GetSection("Properties").GetValue<string>("Application");
var AIConn = builder.Configuration.GetSection("ApplicationInsights").GetValue<string>("ConnectionString");
var log = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.WithProperty("ApplicationName", appname)
.WriteTo.ApplicationInsights(AIConn, new TraceTelemetryConverter())
.CreateLogger();
Log.Information("Log message from Program.cs file");
Log.Warning("Warning Message");
builder.Logging.AddSerilog(log);
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
My .csproj file :
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Serilog.AspNetCore" Version="6.1.0" />
<PackageReference Include="Serilog.Sinks.ApplicationInsights" Version="4.0.0" />
</ItemGroup>
</Project>
In Transaction search, click on any of the trace.
It will be redirected to the End-to-end transaction details.
OutPut in Application Insights :

404 error: Trying to deploy ocelot gateway inside docker to call microservices

We have developed two ASP.NET CORE (5.0) microservices and deployed them inside docker
http://localhost:28621/stock
http://localhost:62362/user
Both are easily accessible from browser.
We have used ocelot gateway for API gateway.
When we deployed it inside docker we got following error
warn: Ocelot.DownstreamRouteFinder.Middleware.DownstreamRouteFinderMiddleware[0] requestId: 0HM8658EF6KHC:00000002, previousRequestId: no previous request id, message: DownstreamRouteFinderMiddleware setting pipeline errors. IDownstreamRouteFinder returned Error Code: UnableToFindDownstreamRouteError Message: Failed to match Route configuration for upstream path: /user, verb: GET. warn: Ocelot.Responder.Middleware.ResponderMiddleware[0] requestId: 0HM8658EF6KHC:00000002, previousRequestId: no previous request id, message: Error Code: UnableToFindDownstreamRouteError Message: Failed to match Route configuration for upstream path: /user, verb: GET. errors found in ResponderMiddleware. Setting error response for request path:/user, request method: GET -------------------------------------------------------------------------------------------------
ocelot.Development.json is as follows
{
"Routes": [
{
"DownstreamPathTemplate": "/user",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 62362
}
],
"UpstreamPathTemplate": "/user",
"UpstreamHttpMethod": [ "Get" ]
},
{
"DownstreamPathTemplate": "/stock",
"DownstreamScheme": "http",
"DownstreamHostAndPorts": [
{
"Host": "localhost",
"Port": 28621
}
],
"UpstreamPathTemplate": "/stock",
"UpstreamHttpMethod": [ "Get" ]
}
],
"GlobalConfiguration": {
"BaseUrl": "https://localhost:5021"
}
}
startup.cs
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddOcelot();
}
public async void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
await app.UseOcelot();
}
}
program.cs
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.AddJsonFile($"ocelot.
{hostingContext.HostingEnvironment.EnvironmentName}.json", true, true);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
Please guide us where we are doing mistake
we are using .net core 5.0
Thanks
Your Ocelot container cannot access the other containers' services with "DownstreamHostAndPorts" settings: {'Host': 'localhost'}. Container's 'localhost' is not the same as the host machine's 'localhost'!
To solve this issue look in this direction:
Create a Docker network
Run all three containers under the same network with --network-alias flag
In the Ocelot json file use the network alias names and default ports (since the containers can talk to eachother directly, there is no need to map external ports!)
Can you please change Routes to ReRoutes. I fixed myself with that. Maybe you forgot to add json file in the program.cs. Here is the code,
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((host, config) =>
{
config.AddJsonFile("Ocelot.json", false, true);
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder .UseStartup<Startup>();
});

Serilog and .NET Core Web API log file isn't created

I'm just starting with Serilog.
Despite all the code samples/tut's, I've found online I just can't get it to output to file (the file isn't even created). My app is a Web API (.NET Core 3.1), I'm referencing
Serilog.AspNetCore(3.4.0)
Serilog.Settings.Configurations (3.1.0)
Serilog.Sinks.File (4.1.0)
My appsettings.json:
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Warning",
"System": "Warning"
},
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "C:\\DEV\\Logs\\mylog.txt",
"rollingInterval": "Day"
}
}
]
}
},
"AllowedHosts": "*"
}
My Program.cs
public static void Main(string[] args)
{
Serilog.Debugging.SelfLog.Enable(Console.Out);
//Read Configuration from appSettings
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
//Initialize Logger
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(config)
.CreateLogger();
try
{
CreateHostBuilder(args).Build().Run();
Log.Information("Application started!");
}
catch (Exception e)
{
Log.Fatal(e, "Application failed to start.");
}
finally
{
Log.CloseAndFlush();
}
}
My controller
public void Post(SampleRequest request)
{
Log.Information("Received request {#request}", request);
}
Not even the Selflog is writing anything to Visual Studio output console Serilog.Debugging.SelfLog.Enable(Console.Out);
Try and enable SelfLog which should help you pinpoint what is going wrong. This call is slightly different to yours.
Add this in Program.cs just after you call .CreateLogger();
Serilog.Debugging.SelfLog.Enable(msg => Debug.WriteLine(msg));
More details - https://github.com/serilog/serilog/wiki/Debugging-and-Diagnostics
I have Serilog logging to a rolling file in a .Net Core 3.1 app.
These are my nuget references:
<PackageReference Include="Serilog" Version="2.9.0" />
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<PackageReference Include="Serilog.Sinks.RollingFile" Version="3.3.1-dev-00771" />
Also, just noticed you don't seem to have a Using section in your appsettings.json:
"Serilog": {
"Using": [ "Serilog.Sinks.RollingFile" ],
"MinimumLevel": "Debug",
"WriteTo": [
{
"Name": "RollingFile",
"Args": {
"pathFormat": "C:\\Logs\\ScreenPop\\Log-{Date}.txt"
}
}
]
},
I figured out what was the problem. I copied settings from some blog and the "WriteTo" element was actually nested inside the "MinimumLevel" one.
The correct settings would be:
{
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "C:\\DEV\\Logs\\mylog-.txt",
"rollingInterval": "Day"
}
}
]
},
"AllowedHosts": "*"
}

Web api netcore set Cors in appsettings.json file

I'm using a webapi .netcore project.
I want to put all the cross settings in the appsettings.json file.
How do I do this?
This is my code:
app.UseCors(x => x.WithOrigins("http://localhost:4200")
.AllowCredentials()
.WithHeaders("content-type")
.WithMethods("GET", "POST", "PUT", "DELETE"));
If you want to set the CORS settings in appsettings.json and use the settings in startup.cs, you can follow the code below:
This is my appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"AllowedOrigins": "http://localhost:4200",
"AllowedHeaders": "content-type",
"AllowedMethods": "GET,POST,PUT,DELETE"
}
This is my partial code in startup.cs:
app.UseCors(x => x.WithOrigins(Configuration.GetSection("AllowedOrigins").Value.Split(","))
.AllowCredentials().WithHeaders(Configuration.GetSection("AllowedHeaders").Value.Split(","))
.WithMethods(Configuration.GetSection("AllowedMethods").Value.Split(",")));
app.UseHttpsRedirection();

ASP.NET 5 host application in IIS 8 with https bindings

Earlier I was having issue hosting ASP.NET 5 application in IIS and now I am able to host it via http. Here is my old post that contains details.
For past couple days I have been trying to enable https for my application over port 443. In launchSetting.json file I updated iisexpress settings to "applicationUrl": "https://servername:443/" with valid certificate. but I still get 404 error when I browse the application in the browser.
Here is my launchSettings.json file:
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "https://servername:443/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"Hosting:Environment": "Development"
}
},
"web": {
"commandName": "web",
"environmentVariables": {
"Hosting:Environment": "Development"
}
}
}
}
Here is my project.json file:
"dependencies": {
"Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
"Microsoft.AspNet.Mvc.Core": "6.0.0-rc1-final",
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
"Microsoft.Extensions.Logging.Debug": "1.0.0-rc1-final",
"Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
"Microsoft.Net.Http.Server": "1.0.0-beta5",
"dnx-clr-win-x64": "1.0.0-rc1-update1",
"Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final"
},
"commands": {
"web": "Microsoft.AspNet.Server.Kestrel"
}
Startup.cs file:
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc() // Add MVC Dependency.
.AddJsonOptions(
opt =>
{
opt.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); // Api convert all property names to CamelCase.
}
);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, ILoggerFactory LoggerFactory)
{
LoggerFactory.AddDebug(LogLevel.Warning);
app.UseIISPlatformHandler();
app.UseStaticFiles();
app.UseMvc(config =>
{
config.MapRoute(
name: "Default",
template: "{controller}/{action}/{id?}",
defaults: new { controller = "App", Action = "Index" }
);
}); // Use MVC from Dependency.
}
// Entry point for the application.
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}
I am not sure if it is right way to enable https in the application, but IIS bindings are configured correctly with valid certificate. So I am not sure why it is still throwing 404 error.
Any help from community is really appreciated. :)

Resources