Handle redirect function when ASP.NET Core Web MVC error in application startup ( program.cs ) - asp.net-core-mvc

I want to handle my net core website able to catch the error and redirect to the error page or other sites if the middleware error or web application build fails at startup.
Methods I have tried
1.Add custom ErrorHandlerMiddleware and redirect page in trycatch,but redirect cause infinite loop and getting error "ERR_TOO_MANY_REDIRECTS"
2.Use "UseExceptionHandler" and errorHandlingPath to Error Controller return and redirect to target page,but getting http error 500
Is it possible to handle redirect to other pages when net core web startup error?

If web application build failed,You may not be able to reach the Error Page
If you want to handle the errors may cause webapplication build failure,you'd better directicty write the response with lambda
app.UseExceptionHandler(x => x.Run(async context=> {
context.Response.StatusCode = 500;
await context.Response.WriteAsync("SomeError");
}));

Related

How to handle Custom Errors With .Net Core 2.2 MVC

I saw on youtube how to handle custom errors but it was with web.config and in dotnet core 2.2 it does not have this file or I'm not finding it through visual studio 2019.
ASP.NET Core doesn't use Web.config, unless you're hosting in IIS, and then only for minimal IIS module configuration. Custom error handling is done via middleware configuration in your Startup.Configure method. This is actually covered in the default project template, though, so it's odd that you don't have something included by default to at least work from. Regardless, you're looking at something like:
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
}
That will generally route any global uncaught exception to a general /Error endpoint, which could be either a controller action or Razor Page. More likely than not, you'll want a little more flexibility, and you will also want to not expose an actual "error" URL in the browser, so you'll probably sub UseExceptionHandler with UseStatusCodePagesWithReExecute:
app.UseStatusCodePagesWithReExecute("/StatusCode","?code={0}");
That will keep the URL, without redirecting and load up a /StatusCode endpoint while passing the specific status code (404, 400, 500, etc.), allowing you to return custom messaging per error type.
All of this and more is in the documentation.

Azure AD in ASP.NET Core MVC web application causes CORB for JavaScript requests

Integration of Azure AD into a ASP.NET Core MVC web application causes Cross-Origin Read Blocking for requests made by JavaScript frontend to ASP.NET controllers.
I am writing an ASP.NET Core MVC application that requires users to login using a Microsoft work account. This works. I added the following code to Startup.cs:
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
})
.AddAzureAd(options => Configuration.Bind("AzureAd", options))
.AddCookie(options =>
{
options.LoginPath = "/Account/SignIn/";
options.AccessDeniedPath = "/Account/AccessDenied/";
});
I am also using Telerik UI widgets for the applications user interface. Because of this, there are multiple places where I use JavaScript to make requests to my ASP.NET controllers. Ex:
function onEvent(e) {
$.post("Controller/Foo", function (data) {
...
});
}
This works great when I'm running and debugging locally using IIS Express but when I deploy the application to our server running IIS I start getting warnings about Cross-Origin Read Blocking in my browsers development tools and none of my javascript functions that make requests to my ASP.NET controllers receive data.
Here is a screenshot of the warnings:
If anyone happens to know how to approach this problem I would be very grateful; I'm new to all of this and I have no idea where to start with this particular problem.
My current thinking is either I need to figure out how to handle the 'Access-Control-Allow-Origin' header in javascript or that there is something that needs to be done in Azure.
The first thing I did was enable CORS in my application but that just allows other domains to make cross-origin requests from my application, which isn't what's happening here.
If anyone comes across this issue with CORB in Chrome and dotnet core please note that in my case I was using the ResponseCache attribute. On the first non cached request it worked and subsequent ones failed with CORB error.
Once I removed the attribute the error went away.
This does not solve the issue but gives one some direction as to where the issue might be.
I did not bother with the response cache as it's no longer needed.
Below was the offending code
[ResponseCache(Duration = 15, Location = ResponseCacheLocation.Any, VaryByQueryKeys = new[] {"key", "type", "identifier", "app"})]

Forbid() returns 404

I have returned Forbid() from a web request, and the browser claims its receiving a 404 instead of a 403.
I have added a handler to the cookie authentication like so...
o.Events.OnRedirectToAccessDenied += ctx =>
{
ctx.Response.StatusCode = (int)HttpStatusCode.Forbidden;
return Task.FromResult(0);
};
But this doesn't appear to be called.
Thus, why is a method that should return a 403 returning a 404?
I had the same issue. These were my steps to fix it:
Temporarily remove all the exception handling like app.UseExceptionHandler("/Home/Error") from Startup. In my case the 404 happened because the exception handling was broken.
Then I got the "real" error: My problem was that I had no authentication configured, and therefore no authentication schemes.
After I added the correct authentication options to Startup (in my case I used a custom authentication handler) I got the correct response code:
services.AddAuthentication(LicenseKeyAuthenticationOptions.Scheme)
.AddScheme<LicenseKeyAuthenticationOptions, LicenseKeyAuthenticationHandler>(LicenseKeyAuthenticationOptions.Scheme, null);
The Forbid() command seems to have an internal ASP.NET MVC controller redirect handling. In case you only want to provide a classic API and want 403 to be returned you should switch the command to
return StatusCode(StatusCodes.Status403Forbidden);
Don't forget to import the using
using static Microsoft.AspNetCore.Http.StatusCodes;
Source: https://stackoverflow.com/a/47708867/828184
So far I'm not aware if this behaviour of Forbid() could be changed.

Cache internal routes with sw-precache

I'm creating a SPA using vanilla JavaScript and currently setting up sw-precache to handle the caching of resources. The service worker is generated as part of a gulp build and installed successfully. When I navigate to the root url (http://127.0.0.1:8080/) whilst offline the app shell displays, illustrating that resources are indeed cached.
I'm now attempting to get the SW to handle internal routing without failing. When navigating to http://127.0.0.1:8080/dashboard_index whilst offline I get the message 'Site can't be reached'.
The app handles this routing on the client side via a series of event listeners on the users actions or, in the case of using the back button, the url. When accessing one of these urls, no calls to the server should be made. As such, the service worker should allow these links to 'fall through' to the client side code.
I've tried a few things and expected this Q/A to solve the problem. I've included the current state of the generate-service-worker gulp task, and with this setup I'd expect to be able to access /dashboard_index offine. Once this is working I can adapt the solution to cover other routes.
Any help much appreciated.
gulp.task('generate-service-worker', function(callback) {
var rootDir = './public';
swPrecache.write(path.join(rootDir, 'sw.js'), {
staticFileGlobs: [rootDir + '/*/*.{js,html,png,jpg,gif,svg}',
rootDir + '/*.{js,html,png,jpg,gif,json}'],
stripPrefix: rootDir,
navigateFallback: '/',
navigateFallbackWhitelist: [/\/dashboard_index/],
runtimeCaching: [{
urlPattern: /^http:\/\/127\.0\.0\.1\:8080/getAllData, // Req returns all data the app needs
handler: 'networkFirst'
}],
verbose: true
}, callback);
});
update
The code to the application can be found here.
Removing the option navigateFallbackWhitelist does not chage the result.
Navigating to /dashboard_index whilst offline prints the following to the console.
GET http://127.0.0.1:8080/dashboard_index net::ERR_CONNECTION_REFUSED
sw.js:1 An unknown error occurred when fetching the script.
http://127.0.0.1:8080/sw.js Failed to load resource: net::ERR_CONNECTION_REFUSED
The same An unknown error occurred when fetching the script. is also duplicated in the 'application > service workers' tab of chrome debug tools.
It's also noted that the runtimeCaching option is not caching the json response returned from that route.
For the record, in case anyone else runs into this, I believe this answer from the comments should address the issue:
Can you switch from navigateFallback: '/' to navigateFallback:
'/index.html'? You don't have an entry for '/' in your list of
precached resources, but you do have an entry for '/index.html'.
There's some logic in place to automatically treat '/' and
'/index.html' as being equivalent, but that doesn't apply to what
navigateFallback is doing...

MVC default redirect Error page doesn't always show

I have a custom error page in my MVC application that's just ~/error/ but when I turn Custom Errors on in the Web.Config like so:
<customErrors mode="On" defaultRedirect="~/error/" />
It only works for 400 errors not server-side 500 errors and instead gives me the following error message on a white page:
"Sorry, an error occurred while processing your request."
How can I just make every single error go to the defaultRedirect page?
500 errors should be handled by the MVC application itself. Custom Errors defined by the web.config are for errors other than 500 errors.
Basically, you need to use the RegisterGlobalFilter method (in global.asax) to add a new HandleErrorAttribute to the filter collection (you'll name the view to use for errors in the HandleErrorAttribute), then create a view that takes as its model System.Web.Mvc.HandleErrorInfo. There is no controller that handles these errors or sends the model to the view, so you can't just redirect to your error page.
You can get more information at http://community.codesmithtools.com/CodeSmith_Community/b/tdupont/archive/2011/03/01/error-handling-and-customerrors-and-mvc3-oh-my.aspx.
EDIT There is an alternative method, where all errors are handled through MVC, shown in How do I display custom error pages in Asp.Net Mvc 3?. Basically, you set up a protected void Application_Error()in your global.asax file to handle all errors, without going through web.config.

Resources