ASP.NET Core Web API over http - c#

I'm working on an ASP.NET Core application, which uses yarp. The application should be only a reverse proxy between outside word and other backend services.
I want to serve this application over http on localhost for development purposes, however, my request is always redirected to https endpoint. I'm using .NET 6.
I removed UseHttpsRedirection() but it didn't help. In logs, I see that application is served over http://localhost:5000 and https://localhost:5001, but if I open http://localhost:5000, it is redirected to https://localhost:5000 - what is wrong. In browser, I see 307 Internal Redirect to https://localhost:5000/
I want to achieve that application is working over http and https as well on localhost.
This is my config:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
var proxyBilder = builder.Services.AddReverseProxy();
proxyBilder.LoadFromConfig(builder.Configuration.GetSection("ReverseProxy"));
var app = builder.Build();
// Configure the HTTP request pipeline.
app.MapGet("", () => $"It works! {string.Join(",", app.Urls)}");
app.MapReverseProxy();
app.UseCors();
app.UseAuthorization();
app.MapControllers();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.Run();
launchsettings.json:
{
"profiles": {
"Vocabulary.ServiceGateaway": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_URLS": "http://+:5000"
},
"dotnetRunMessages": true,
"useSSL": false
}
},
"$schema": "https://json.schemastore.org/launchsettings.json"
}

Related

Accessing asp.net core api from react app (both containerized)

So I have a containerized app which consists of react + asp.net core + keycloak + nginx.
I don't want to publish the port of the API to the internet, I only want it to be accessible in the containers' network.
But I can't manage to make my API calls from the React app.
Right now I'm doing them here:
https://localhost:7266
docker-compose of asp.net core container
mediere-api:
container_name: best-asp.net
image: ${DOCKER_REGISTRY-}mediere-api
build:
context: ..
dockerfile: Dockerfile
env_file:
- .env
depends_on:
- db
expose:
- "7266"
volumes:
- ../certs/certificate.pfx:/etc/https/certs
dockerfile of it
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["mediere-API.csproj", "."]
RUN dotnet restore "mediere-API.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "mediere-API.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "mediere-API.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "mediere-API.dll"]
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
deleted
}
}
launchSettings.json
{
"profiles": {
"mediere_API": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
},
"applicationUrl": "https://localhost:7266",
"dotnetRunMessages": true
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
}
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
"publishAllPorts": true,
"useSSL": true
}
}
}
.env
#ASP.Net core
ASPNETCORE_STATICWEBASSETS="/app/bin/Debug/net6.0/mediere-api.staticwebassets.runtime.CT.json"
ASPNETCORE_ENVIRONMENT=Production
ASPNETCORE_URLS=https://localhost:7266
Proogram.cs
using mediere_API.DataLayer;
using mediere_API.DataLayer.Repository.Implementations;
using mediere_API.DataLayer.Repository.Interfaces;
using mediere_API.Extensions;
using mediere_API.Middleware;
using mediere_API.Processors.Implementations;
using mediere_API.Processors.Interfaces;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
//Servicii
builder.Services.AddControllers();
builder.Services.ConfigureSwagger();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddRouting(options => options.LowercaseUrls = true);
builder.Services.AddRepositories();
builder.Services.AddProcessors();
//UnitsOfWork
builder.Services.AddScoped<ISchemaUnitOfWork, SchemaUnitOfWork>();
builder.Services.AddScoped<IMainUnitOfWork, MainUnitOfWork>();
//AutoMapper
builder.Services.AddAutoMapper(typeof(Program));
//Keycloak
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, o =>
{
o.MetadataAddress = "https://keycloak:8443/auth/realms/best-realm/.well-known/openid-configuration";
o.Authority = "https://keycloak:8443/auth/realms/best-realm";
o.Audience = "account";
o.RequireHttpsMetadata = false;
});
//CORS
builder.Services.AddCors(options =>
{
options.AddDefaultPolicy(
policy =>
{
policy.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.WithExposedHeaders("FileName");
});
});
builder.Services.AddDbContext<EfDbContext>();
builder.Services.AddDbContext<SchemaEfDbContext>();
var app = builder.Build();
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseMiddleware<SchemaHandlingMiddleware>();
app.UseCors();
app.UseAuthorization();
app.MapControllers();
app.Run();
With these settings, my API calls don't seem to reach the Docker container. I get:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost:7266/api/proiecte. (Reason: CORS request did not succeed). Status code: (null)
status code null means that the container couldn't be reached I think.
So what's wrong with my settings?
How should I do my API calls to the ASP container from docker in order for them to work?
Thanks.
Same Origin serving approach using reverse proxy:
You should reverse proxy your API inside your nginx configuration.
Something like this:
nginx.conf:
location /
proxy_pass: TO_YOUR_REACT_APP
or: SERVER_YOUR_REACT_APP_STATIC_FILES
location /api
proxy_pass: TO_YOUR_API
This approach makes your API and REACT app to be at the same origin.
So there will be no CORS error.
Enabling CORS for requests that you are sending via browser. Please share a screen shot from your browser console error in order th help you with.

ASP.NET Core default template project fails with HTTP ERROR 404 or Exception

I have a problem with ASP.NET Core MVC or Razor applaunch.json.
I use a default template to create a project with default settings:
ASP.Net Core Web App - Dot Net 6
ASP.Net Core Web App MVC - Dot Net 6
This is my applaunch.json:
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:18583",
"sslPort": 44326
}
},
"profiles": {
"WebApplication12": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "https://localhost:7081;http://localhost:5081",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
And program.cs :
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
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();
After launch console shows that no problem with listening to ports :
But I get an exception for my ASP.NET Core MVC projects:
And I get 404 for Razor Pages:
All configurations are default template configurations.
Did anyone experience the same problem?
I solved the problem by using Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation package and adding the following service:
For ASP.NET Core Razor template
builder.Services.AddRazorPages().AddRazorRuntimeCompilation();
And for the MVC project template:
builder.Services.AddControllersWithViews().AddRazorRuntimeCompilation();
The second solution is to use dotnet run watch either in Developer Power Shell or Command-Line.

Launch SignalR from .NET Core 2.1 Web API project inside IIS

I built with Visual Studio 2017 a new project: "ASP.NET Core Web Application", then "API" project (ASP.NET Core 2.1) and I added SignalR as shown in this guide: https://code-maze.com/netcore-signalr-angular/
I'm able to launch the project with console by commenting the IIS Express profile in launchSettings.json as follows:
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:64155",
"sslPort": 0
}
},
"profiles": {
/*"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": false,
"launchUrl": "api/values",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},*/
"WebApplication2": {
"commandName": "Project",
"launchBrowser": false,
"applicationUrl": "http://localhost:5001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
In that case my (Ionic 4) client succeeds to connect:
[2020-08-22T10:41:21.539Z] Information: WebSocket connected to ws://localhost:5001/testHub?id=iUNCgO8mFOt7MjdQB-Cn_Q.
However, if i start debugging in IIS Express (without commeting the IISExpress profile, i tried also to use different values for launchBrowser property), the API is working but it seems that SignalR does not get launched.
EDIT:
This is the error shown on console when i launch Visual Studio project in IIS Express, the error is the same that i would get if i launch the client without starting the debug on Visual Studio 2017 so, since it is working when the project is launched as a console app, i thought I was missing some configuration.
What is the correct configuration to start SignalR keeping the IIS Express default launch method? I would like at the end to be able to publish solution and deploy it to IIS. Starting site from IIS is enough to setup SignalR configuration?
Also, is it possible at the end to log SignalR messages (handling events) in a given log file?
This is my Startup.cs file:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WebApplication2.SignalR;
namespace WebApplication2
{
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.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSignalR();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials());
app.UseMvc();
app.UseSignalR(routes =>
{
routes.MapHub<TestHub>("/testHub");
});
}
}
}
And this is Program.cs:
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
namespace WebApplication2
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}
Is it possible to launch SignalR from Main method?
Have you tried adding cors to your startup.cs file?
I posted solution as an edit but maybe it was not easy to see.
I found the correct answer to my issue here: https://stackoverflow.com/a/57654495/6449672: after moving to IIS Express profile I had to change the url called by client from http://localhost:5001/testHub to http://localhost:64155/testHub.

How to launch dotnet core mvc app on a different port?

My dotnetcoreapp2.2 application runs fine under port 5001 (after configuring the dev cert) but I cannot get it to launch under any other port. Here are the components I've attempted configuring...
Program.cs:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseUrls("http://localhost:5000")
.UseKestrel()
.UseStartup<Startup>()
.UseApplicationInsights();
Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseAuthentication();
if (env.IsDevelopment() || env.IsEnvironment("Developer"))
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
}
launch.json:
"args": [
"--urls", "http://localhost:5000"
],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}"
}
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Developer",
"ASPNETCORE_URLS": "http://localhost:5000"
},
Am I missing something or have something configured incorrectly?
This issue generally occurs when using IIS / IIS Express, so rid of the IIS.
Run web server as .net core console application, instead of using IIS Express(it has own port configuration file for each project, and it is annoying).
To do that: Change Debug Profile in Project's Properties > Debug >
change the value of Profile from IIS Express to "select-your-project-name"
change the value of Launch from IIS or IIS Express to Project
Then, you will see Web Server Settings on bottom of the same window, you can use it to change port(IIS configs are not using anymore).
Also you should change default debugger from IIS Express to "select-your-project-name" (you will see where you clicked to debug your project)

How to change base url of Swagger in ASP.NET core

By default when you enable swagger in ASP.NET Core project it's available on url:
http://localhost:<random_port>/swagger/ui
I would like to use a different base url instead of /swagger/ui. How/where can i configure that?
I found that for older versions you can configure the RootUrl but there aren't similiar method in ASP.NET Core:
.EnableSwagger(c =>
{
c.RootUrl(req => myCustomBasePath);
});
For ASP.NET Core 2 (and using Swashbuckle.AspNetCore.Swagger -Version 4.0.1), a couple things can be done for a full configuration of changing the default swagger UI base URL.
If you want to add "mycoolapi" to the beginning of your default swagger UI URL, like this: http://<server>/mycoolapi/swagger, then do the following:
In your Startup.cs Configure method:
app.UseSwagger(c =>
{
c.RouteTemplate = "mycoolapi/swagger/{documentname}/swagger.json";
});
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/mycoolapi/swagger/v1/swagger.json", "My Cool API V1");
c.RoutePrefix = "mycoolapi/swagger";
});
Then, if you currently have your launchSettings to launch browser at swagger UI upon startup (for development purposes), update your launchSettings.json file profiles section similarly:
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "mycoolapi/swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"MyProject.Web": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "mycoolapi/swagger",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
The new swagger version provides you with a property called RoutePrefix.
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
c.RoutePrefix = "docs";
});
Should work for .net core
Other answers didn't work for me in .NET 5. Here is how I added 'docs' to the route
app.UseSwagger(c => c.RouteTemplate = "/swagger/docs/{documentName}/swagger.json");
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/docs/v2/swagger.json", "My API"));
Open the launchSettings.json file.
Under the "profiles" node depending on your setup you should have one or more profiles. In may case I had "IIS Express" and another with named with my project name (e.g WebApplication1 ), now changing the launchUrl entry to "launchUrl": "swagger" solved my problem.
If this does not work and you have other profiles do the same and test.
You can do this as well in Config
app.UseSwaggerUI(c =>
{
c.RoutePrefix = string.Empty;
c.SwaggerEndpoint("/swagger/v1/swagger.json", "MY API");
});
I had to dig through the original docs because all the above solutions did not work. This code in Startup.cs is what is working for me:
app.UseSwagger();
app.UseSwaggerUI(c => {
c.SwaggerEndpoint($"./v1/swagger.json", "SapWeb v1");
});
My site is a subsite in IIS. So, at first, I had to set PathBase:
app.UsePathBase($"{pathbase}");
The UseSwaggerUi() extension method to enable the middleware in the Configure method of the StartUp class takes two variables. A baseRoute which is on swagger/ui by default, and swaggerUrl which is on swagger/v1/swagger.json by default. Simply provide a different baseRoute.
//Swagger will be available under '/api' url
app.UseSwaggerUi("api");
If people would like to learn more about configuring Swagger for ASP.NET Core, I've written a blogpost to get started: https://dannyvanderkraan.wordpress.com/2016/09/09/asp-net-core-1-0-web-api-automatic-documentation-with-swagger-and-swashbuckle/

Categories