Blazor handling asp pages - asp.net

I have migrated old ASP pages (www.company.com/index.asp) to the Blazor project and I am trying to display "Not Found page" to the users accessing web site via "old bookmarks" like www.company.com/contact.asp.
I have tried in the _host.cshtml redirection, but condition is never met.
#if ((Request.Path.ToString()?.Contains(".asp")).GetValueOrDefault())
{
LocalRedirect("/NotFound");
return;
}
I have tried to add #page directive #page "/{oldPage}.asp" to NotFound blazor component, but application does not render any page at all then.
I would rather solve *asp handling in the application itself rather than on the IIS or proxy, because I do not have direct access to proxy/IIS settings.
Is there any hint how to solve this ?

The solution is to add to Startup.cs endpoints.MapGet("/{page}.asp", async x => { x.Response.Redirect("/NotFound"); });
Full snippet:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
endpoints.MapGet("/{page}.asp", async x => { x.Response.Redirect("/NotFound"); });
});

Related

ASP.NET serving angular app and deployUrl is deprecated

I have an ASP.NET app (.NET 6.0), and I have a route /ngxapp which serves my angular 13 app. The angular app is copied to wwwroot/ngxapp folder (see below how it's built).
I've been using this .NET code for years to deliver angular app:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
// this is for reverse proxy (NGINX)
app.UseForwardedHeaders(new()
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
}
app.UseHttpsRedirection();
// this must be before the next (angular) section, otherwise 404's are not handled
app.UseStatusCodePagesWithReExecute($"{ANGULAR_APP_ROUTE_S}/404");
app.Use(async (context, next) =>
{
RewriteXFrameOptionsHeader(context);
await next();
RedirectEmptyRootToAngularApp(context, ANGULAR_APP_ROUTE_S);
await RewriteAssets(context, next);
await RedirectForAngular(context, next, ANGULAR_APP_ROUTE_S);
});
app.UseDefaultFiles(new DefaultFilesOptions {DefaultFileNames = new List<string> {"index.html"}});
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapRazorPages();
});
It allows to open angular app even when user requests for some non-root angular route (for example, https://<domain>.com/ngxapp/someroute-1/subroute/etc). Basically, everything works like a charm.
Now, when I build an angular app I've always used --deploy-url=/ngxapp/ param, like so (from windows batch .cmd file):
call ng build --base-href /%folder% --deploy-url /%folder%/ --configuration=production
The latest version of angular compiler shows me the warning about deployUrl:
Option "deployUrl" is deprecated: Use "baseHref" option, "APP_BASE_HREF" DI token or a combination of both instead. For more information, see https://angular.io/guide/deployment#the-deploy-url.
I read the docs on APP_BASE_HREF and built angular app without --deploy-url parameter. Also, used APP_BASE_HREF:
#NgModule({
declarations: [AppComponent, CreateUrlComponent, NotAuthorizedComponent, FormFocusDirective],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
...
],
providers: [
{ provide: APP_BASE_HREF, useValue: environment.baseHref }, // baseHref = "/ngxapp"
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule {
constructor() {}
}
But now, when I run ASP.NET app with the angular app in place (opening https://localhost/ngxapp in the browser), the requests of all .js files are empty and their MIME type is text/html. Basically, they're not found.
If I return back to using deploy-url parameter in the angular build, everything works!
What am I missing here?
Comes down to this
When --deploy-url is used, the request Url is correct:
https://localhost:44389/ngxapp/filename.js
because the script block contains correct url's:
<script src="/ngxapp/runtime.js" type="module"></script>
When --deploy-url is not used, ngxapp part is missing:
https://localhost:44389/filename.js
and the script block is:
<script src="runtime.js" type="module"></script>
I made it work. Here's how I wanted the angular part to work within ASP.NET app:
if I have a special route for angular app called /ngxapp within my ASP.NET application, I want any link containing '/ngxapp' part to work seemlessly. For example, if a user paste https://example.com/ngxapp/child/subchild to a browser address, and the angular app does have child/subchild routes, then ASP.NET app should serve the https://example.com/ngxapp/index.html and the angular router takes over and serves child/subchild.
The problem is when ASP.NET serves angular's app index.html from /ngxapp, the script tags in the index file must have a valid path related to wwwroot/ngxapp/ folder (scr='/ngxapp/some-angular-file.js, and not just src='/some-angular-file.js'). This works when --deploy-url flag is used.
Now, when the flag is deprecated, I had to create a rewrite rule in ASP.NET which actually catches any file served from angular app folder and rewrites it to the correct path accordingly: from /whatever-angular-file.js to /ngxapp/whatever-angular-file.js.
With this custom URL rewriting rule in place, everything works as expected, and --deploy-url is not needed.

Hangfire Dashboard broken after deployment - not load css and js

when working the development the dashboard is seen correctly, but when it is uploaded to production not load the css and js files
project version net core 3.1 api
hangfire error
my startup
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
Authorization = new[] { new CustomAuthorizationFilter() }
});
I tried the following without results, the server is windows and the authorization filter is simple... I'm not sure what the problem is... but it doesn't load the css and js files
app.Use((context, next) =>
{
// note : comment this to debug locally
context.Request.PathBase = "jobs";
return next();
});

Deployed to Azure: Fixing the Mime Type sends an empty css file to the server

Everything is working fine locally. But when deployed to Azure, loading the css shows this error:
Resource interpreted as Stylesheet but transferred with MIME type text/plain
It happens in all the browsers.
The application loads a spa in react.
These are the middlewares I am using in this order.
if (Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
// 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.UseHttpsRedirection();
app.UseStatusCodePagesWithReExecute("/Home/Error", "?statusCode={0}");
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseOurCustomAuthenticate();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action}/{id?}");
routes.MapRoute(
name: "api",
template: "api/{controller}/{action}/{id?}");
});
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (Environment.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
});
The custom authenticate middleware that we are using checks if the path starts with "/styles" it will not do anything and let it load.
This is the cshtml file where I include the css file:
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="~/styles/notFound.css">
</head>
<body class="body-content">
This is where the styles and images are
The image is being loaded properly on the server, only the style have this problem.
So in my custom middleware I did this:
if (httpContext.Request.Path.StartsWithSegments("/styles"))
{
httpContext.Response.ContentType = "text/css";
}
Now the content-type is correct in the network tab, but the style is not still loading. When I click on the css file it is an empty file.
I have read a lot of posts regarding this issue, but couldn't still solve it.
At this point I had to see if the stylesheet is actually deployed.
To do so, I pulled the contianer and run it locally to see what files are copied there.
I found that the styleSheet is copied under a folder "Styles" with capital "S" instead of "styles" with small "s". We use git for our source control and git didn't catch the rename I made to this folder.
This is how to commit such a change with git case sensitive. Renaming the folder properly fixed the problem for me.

web api "get" method results in a view

I have a .net core 2.0 web api with the following get method:
[HttpGet]
public async Task<IEnumerable<Customer>> Get()
{
return await customerDataProvider.GetCustomers();
}
In the startup class i have the following in configuration:
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}");
});
when i run the application i get the results displayed as raw json in the browser.
I would like to add a view and to handle the results in that view meaning display them in a table and add some filtering and sorting options.
How can i achieve this? I saw different articles on how to add a view or a razor page to a project but none of them was similar to my case..
Thanks!

Ignore embedded resources routing ASP.NET 4 WebForms

I am using routing in asp.net 4 webforms. I have a theme dll which contains all the images, css and js files required for look and feel. I have only 1 page which dynamically loads the control in the page. I use routing to distinguish the request. Following routes are defined:
routes.Ignore("{resource}.axd/{*pathInfo}");
routes.MapPageRoute("Default-All-Pages", "Pages/{*OtherParams}", "~/Default.aspx", false);
Handler for managing the embedded resources is already defined. When the application is executed it by virtue of code, redirects the request to default.aspx. it then goes ahead to load the css file and again routes the request to default.aspx.
I want it to route the css/jpg request to virtual path handler and not the page. What route should I define so that the request for files will not be handled by default.aspx page?
routes.Ignore("{*allaspx}", new { allaspx = #".*\.aspx(/.*)?" });
routes.Ignore("{*allcss}", new { allcss = #".*\.css(/.*)?" });
routes.Ignore("{*alljpg}", new { alljpg = #".*\.jpg(/.*)?" });
routes.Ignore("{*alljs}", new { alljs = #".*\.js(/.*)?" });
This solved my problem.
The same way you're ignoring HttpHandlers, you can add ignore rules for css and jpg files:
routes.Ignore("{resource}.css/{*pathInfo}");
routes.Ignore("{resource}.jpg/{*pathInfo}");
These will be excluded from the route table and will be handled by any registered handlers/modules/ISAPI filters.

Resources