Asp.Net Core middleware pathstring startswithsegments issue - asp.net-core

Have a Asp.NET Core 2.0 application and I would like to map any path that does not start with /api to just reexecute to the root path. I added the below but doesn't seem to work:
app.MapWhen(
c => !c.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase),
a => a.UseStatusCodePagesWithReExecute("/")
);
Not using MapWhen() and just using app.UseStatusCodePagesWithReExecute("/") works for all paths not root. Just want to add filtering for all paths not root and not /api. Any ideas on how to do this?

Branched pipeline does not work correctly here because you have not added MVC middleware after status code page middleware. Here is the correct pipeline setup:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.MapWhen(
c => !c.Request.Path.StartsWithSegments("/api", StringComparison.OrdinalIgnoreCase),
a =>
{
a.UseStatusCodePagesWithReExecute("/");
a.UseMvc();
});
app.UseMvc();
}
Note that middleware order matters here, you should add status code page middleware before MVC.
However using conditional pipeline seems like overkill here. You could achieve your goal with URL Rewriting Middleware:
var options = new RewriteOptions()
.AddRewrite(#"^(?!/api)", "/", skipRemainingRules: true);
app.UseRewriter(options);
app.UseMvc();

Related

Swashbuckle Swagger Try It Out behind NGINX reverse proxy

I'm trying to make the swaggerUI Try it out function to work behind NGINX reverse proxy.
I'm using ASP.net Core with the package Swashbuckle Swagger
Since I have multiple API I added a subdomain to my nginx config.
When I use try it out it sends the request to
http://{server-ip-address}/api/myendpoint
instead of
http://{server-ip-address}/myapi/api/myendpoint
My goal is to add the myapi to the address of Try it out function.
I'm not sure if I should edit my NGINX config or my ASP.net core configuration.
Thanks for your help!
You can try in Startup.cs:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseSwagger(opt =>
{
opt.PreSerializeFilters.Add((swagger, httpReq) =>
{
var serverUrl = $"http://{httpReq.Host}/myapi/api/myendpoint";
swagger.Servers = new List<OpenApiServer>{new() { Url = serverUrl }};
});
});

Blazor Server Side Localization without cookie

So Im trying to add Localization without a cookie to my Blazor Server Side project.
In the documentaition https://learn.microsoft.com/en-us/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0#provide-ui-to-choose-the-culture it says:
Use of a cookie ensures that the WebSocket connection can correctly propagate the culture. If localization schemes are based on the URL path or query string, the scheme might not be able to work with WebSockets, thus fail to persist the culture. Therefore, use of a localization culture cookie is the recommended approach.
So I know its not recommended, but I would like it to be path-based anyway if possible. Can it be done with the standard services.AddLocalization(); and IStringLocalizer, or do I have to build a custom one?
For Localization, I prefer a direct, clear, and readable link that contains the language's first 2 letters (like: mysite.com/en/mypage ), which allows having the correct link using exactly the language needed.
The only solution I found that works perfectly with Blazor Server without the need for Cookies was using the package "BlazorServerUrlRequestCultureProvider" created by "Pier-Luc Bonneville"; it is effortless to use and gives excellent results.
Usage:
Install the package BlazorServerUrlRequestCultureProvider (worked perfectly for me with .Net 5.0):
Install-Package BlazorServerUrlRequestCultureProvider -Version 1.0.0
Startup.cs:
using BlazorServerUrlRequestCultureProvider;
// ...
//------------------------------
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// ...
// Set the Resources folder name:
services.AddLocalization(options => options.ResourcesPath = "Resources");
// ...
}
}
//------------------------------
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseHttpsRedirection();
app.UseStaticFiles();
#region Localization
var supportedCultures = new[]
{
new CultureInfo("en"),
new CultureInfo("ar"),
};
var options = new RequestLocalizationOptions
{
// Select a default language:
DefaultRequestCulture = new RequestCulture("en"),
// For Numbers, Dates, etc:
SupportedCultures = supportedCultures,
// For strings that we have localized in .resx files:
SupportedUICultures = supportedCultures
};
app.UseUrlRequestLocalization(options);
#endregion
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
app.UseRequestLocalization();
}
That was just all you need! No Cookies nor Controllers!
Now use StringLocalizer as usual (in my case, the resource files names were App.resx and App.ar.resx inside the Resource folder):
MyPage.razor:
#page "/ar/MyPage"
#page "/en/MyPage"
#inject IStringLocalizer<App> localizer
<h1>#localizer["My Translated Text Here !"]</h1>
All Thanks & Credits goes to "Pier-Luc Bonneville" for his wonderful work. Project Website , NuGet .
--
Bonus:
To make your life much easier, use the tool ResXManager to easily manage and translate resource files, it's a free and great tool, and it will save you a lot of time.

How to Redirect HTTP to HTTPs in ASP.NET Core?

I want to redirect a HTTP request to HTTPS. How can I do in .Net Core 2.0?
I tried to add the below code in the startup.cs file but this is not working. Can any one help me for this?
services.AddHttpsRedirection(options =>
{
options.RedirectStatusCode = StatusCodes.Status307TemporaryRedirect;
options.HttpsPort = 443;
});
Details about the code:
When I run my project first time, the Configure() and AddHttpsRedirection() gets called.
Then after I change https to http only after that it's not working means its not call any function from stratup.cs
I did this code and try to redirect to https, but page is just loading, it's not redirecting, Even worse, I am not able to call AddHttpsRedirection function.
I have a .NET Core 2.1 project and I use the following:
Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IServiceProvider services)
{
...
app.UseHttpsRedirection();
...
}

AspNetCore Swagger/Swashbuckle and Virtual Directories

I'm struggling with getting the configuration for Swagger/Swashbuckle correct in an Asp.Net core 2.0 web api. I've followed the examples, which all work brilliantly when working at the root folder/localhost. As many others have pointed out, I too am seeing different behavior when working in a virtual folder on the server. I've examined this question - IIS site within virtual directory Swagger UI end point which is similar, but the solution provided there is not working.
My startup.cs file has the following block for configuring services:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddSwaggerGen(c =>
{
c.DescribeAllEnumsAsStrings();
c.IncludeXmlComments(string.Format(#"{0}\EmployeeService.xml", System.AppDomain.CurrentDomain.BaseDirectory));
c.SwaggerDoc("v1", new Info
{
Version = "v1",
Title = "Employee Service"
});
});
...
}
And my Configure method looks like this:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Employee Service API");
});
app.UseMvc();
}
I've tried this with and without adding the RoutePrefix to the SwaggerUI section.
As I mentioned, I'm running .Net Core 2.0.3, I have the Nuget package Swashbuckle.AspNetCore 2.3.0 referenced.
What I get in the app regardless of what I do with the path is a 404 on the /swagger/v1/swagger.json file when I try to access {server}/{virtualdirectory}/swagger. The UI loads, but it won't load the json file, as it always tries to find it at server root.
Can someone point me in the right direction?
You must check your [http] route , dont use [routes] before http`s tag.
you must add a api route on the top and remove all routes before them Http:
[Route("api/[controller]")]
public class asteriskAPI:Controller
{ ........
}
and like this:
[HttpGet]
public ActionResult<List<ast_cel>> GetAll()
{
...
}
You need to change your app.UseSwaggerUI method to this
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("./swagger/v1/swagger.json", "Employee Service API");
});
Note the period.
Source: https://learn.microsoft.com/en-us/samples/aspnet/aspnetcore.docs/getstarted-swashbuckle-aspnetcore/

How to ignore routes in MVC6

I'm developing a very simple SPA style application and I don't want to use razor, so I just need it to serve up HTML files (from the wwwroot folder), except for when the js calls my API controllers. In Web API 2 you could get the router to ignore HTML files so they are served directly e.g.
config.Routes.IgnoreRoute("Html", "{whatever}.html/{*pathInfo}");
similar to this example: http://www.strathweb.com/2014/04/ignoring-routes-asp-net-web-api/ is the IgnoreRoute functionality just not implemented or has it been changed?
At the moment if I have app.UseMvc(); in my Startup.cs any get request to "/" gets me this exception:
An unhandled exception occurred while processing the request.
InvalidOperationException: The view 'Index' was not found. The following locations were searched:
/Views/Home/Index.cshtml
/Views/Shared/Index.cshtml.
Microsoft.AspNet.Mvc.Rendering.ViewEngineResult.EnsureSuccessful()
But when I leave it without MVC it serves up the index.html file when you request "/" - obviously my API controllers won't work then though.
I think if you want to serve index.html even when your MVC option is enabled? If so you have to change one setting.
When you enable MVC there is a default route added to search for Home/Index when your url is like http://localhost:yourport.
When you disable MVC it will serve index.html as no route is present in that case.
So if you want to serve index.html when MVC is enabled then add the following in Configure function before using MVC.
app.UseDefaultFiles(new Microsoft.AspNet.StaticFiles.DefaultFilesOptions() { DefaultFileNames = new[] { "index.html" } });
// your UseMVC goes here.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseMvc();
}