HttpContext.Current.Request.Url.AbsolutePath generate error in global.asax file - c#

I am am using HttpContext.Current.Request.Url.AbsolutePath in global.asax file in one of teh functions to get page related details from database but it fails with following error.
`string _result = Helper.GetPageDetails( HttpContext.Current.Request.Url.AbsolutePath);`
Can i use this HttpContext.Current.Request.Url.AbsolutePath here i need to get the absolutePath of URL and i am getting following error
An exception of type 'System.Web.HttpException' occurred in System.Web.dll but was not handled in user code
Additional information: Request is not available in this context
I catch this in try{} i get following error message details
ex = {"Request is not available in this context"}

This means there is no request associated with the current method call (thread). I am guessing you are calling HttpContext.Current.Request.Url.AbsolutePath from a seperate thread than the one from the request. Without further info thats all i can say

In global.asax you use
Context.Request
as a replacement for
HttpContext.Current.Request

Related

Handling exceptions during localizing in .net5

I would like to ask you if it is possible to handle exception during localizing? For instance I have made recently mistake in my resx file, and my localizer caused that in one language users got error (in translated version I wrote something like "foo {2} bar" instead of "foo {0} bar". I would like to handle this exception that localizer returns the "not translated" string.
Is it possible to write some kind of special exception handler for localizer? Should it implements any interface or something?
Many thanks for your answer.
I think you might need to custom a Resource filters with OnResourceExecuted().
Filter types
Each filter type is executed at a different stage in the filter pipeline:
Authorization filters
run first and are used to determine whether the user is authorized for the request. Authorization filters short-circuit the pipeline if the request is not authorized.
Resource filters
Run after authorization.
OnResourceExecuting runs code before the rest of the filter pipeline. For example, OnResourceExecuting runs code before model binding.
OnResourceExecuted runs code after the rest of the pipeline has completed.
Action filters
Run code immediately before and after an action method is called. Can change the arguments passed into an action. Can change the result returned from the action. Are not supported in Razor Pages.
Exception filters
apply global policies to unhandled exceptions that occur before the response body has been written to.
Result filters
run code immediately before and after the execution of action results. They run only when the action method has executed successfully. They are useful for logic that must surround view or formatter execution.
The following diagram shows how filter types interact in the filter pipeline.
i use a simpler way without any middle ware ,i translate the exception messages into localized string as below ,
call the method in your catch with the original exception message
catch (Exception dex)
{
return Json(new { success = false, responseText = Models.SiteUtils.FriendlyErrorMessage(dex) });
}
method for localization of error messages ,will search for the exception message and get your version of it ,
notice i use Message.Contains(x.OriginalError) so i do not need to translate he whole message exactly ,you may decide to use exact match if you need based on your own logic
public static string FriendlyErrorMessage(Exception dex)
{
var Message = dex.Message;
var listOfStrings = new tblErrorMsgMappingVM().GetAll().ToList();
var ErrorMessage = listOfStrings.Find(x => Message.Contains(x.OriginalError));
if (ErrorMessage != null)
{
Message = ErrorMessage.ErrorMessage;
}
else
Message = "Unknown Error ,pelase review the log";
var value = new tblLocalizationRecordsVM().GetResourceValue(Message, "ErrorMsg");
return value;
}

.Net Core Identity 2 Provider login Cancel leads to unhandled exception

I've added LinkedIn as a provider. I have implemented the login and register with LinkedIn without any issue. In the use case where the user CANCELS from within the provider Pages (either linkedIn login or cancels the authorization of the app) the identity middleware seems to throw an unhandled exception:
An unhandled exception occurred while processing the request.
Exception: user_cancelled_login;Description=The user cancelled LinkedIn login
Unknown location
Exception: An error was encountered while handling the remote login.
Microsoft.AspNetCore.Authentication.RemoteAuthenticationHandler.HandleRequestAsync()
System.Exception: user_cancelled_login;Description=The user cancelled LinkedIn login
Exception: An error was encountered while handling the remote login.
The provider setup in startup defines the callback:
services.AddAuthentication().AddOAuth("LinkedIn", "LinkedIn", c =>
{
c.ClientId = Configuration["Authentication:LinkedIn:ClientId"];
c.ClientSecret = Configuration["Authentication:LinkedIn:ClientSecret"];
c.Scope.Add("r_basicprofile");
c.Scope.Add("r_emailaddress");
c.CallbackPath = "/signin-linkedin";
....
And As I have said the middleware seems to handled ALL other cases except where the user cancels within the LinkedIn pages. The return URL from LinkedIn looks correct:
https://localhost:44372/signin-linkedin?error=user_cancelled_login&error_description=The+user+cancelled+LinkedIn+login&state=CfDJ8MA7iQUuXmhBuZKmyWK9xeAgBBkQvnhf1akLhCIn9bsajCPUf7Wg22oeZBH9jZOIY3YrchMSWZ4dH7NQ1UngLKEuqgU-IHfBglbgJDtS-wc4Z-6DnW66uR0G1ubvNVqatFJHYv17pgqZT98suVkvKgihcJdbNEw7b1ThkuFbn9-5EcYhQ5ln6ImoTgthT8io1DOcCfc_-nBVfOa93a6CpUJTsZc9w93i70jn5dKKXSLntZe0VyRSA0r0PKc5spu5En-0R1rxiLjsjo4dy89PV3A
But never gets to my ExternalCallback controller method where the other cases like successful login/authorization are handled??
I'm wondering if this is working for anyone else with 3rd part providers?
There's a Github issue that explains what's happening here in more detail, with a bit of information as to why it's happening and even an indication that this won't be "fixed":
Handling the RemoteFailure event is the right thing to do. We should update our docs/samples to show how to handle that event and at least show a more appropriate message to the user. The error page sample could include a link to enabled the user to try logging in again.
Unfortunately it's difficult to implement this event in a very generic way that's also super useful because each remote auth provider has its own behavior for different types of failures.
The workaround for this (as quoted above) is to handle the RemoteFailure event:
services.AddAuthentication().AddOAuth("LinkedIn", "LinkedIn", c => {
// ...
c.Events.OnRemoteFailure = ctx =>
{
// React to the error here. See the notes below.
return Task.CompletedTask;
}
// ...
});
ctx is an instance of RemoteFailureContext, which includes an Exception property describing what went wrong. ctx also contains a HttpContext property, allowing you to perform redirects, etc, in response to such exceptions.
I've found the following to work well for me, based on this and similar to Kirk Larkin's answer. The part that took a little figuring out was where to redirect to, without causing problems for subsequent login attempts.
services.AddAuthentication().AddOAuth("LinkedIn", "LinkedIn", c =>
{
...
c.Events = new OAuthEvents()
{
OnRemoteFailure = (context) =>
{
context.Response.Redirect(context.Properties.GetString("returnUrl"));
context.HandleResponse();
return Task.CompletedTask;
}
};
};

What to do/throw when you have hit a API limit

I am using a API with a limit, there is a high possibility that I could hit the limit.
I am wondering how people handle this? Do they check if they hit the limit and then throw an exception? If so what type of exception?
Are there any best practices?
I am able to see if I hit the limit like below:
if (!string.IsNullOrEmpty(result.error))
{
// we have hit a limit
}
This API is used for a MVC application.
I am caching the ActionResult methods with the API content ([OutputCache]). If the Action method does not recieve the API result then the view will be empty, but if i throw something it will end up on the custom errors page.
You should first log what happened using the information you receive from result.error and then create a custom exception and throw it including the original error message.
if (!string.IsNullOrEmpty(result.error))
{
// we have hit a limit
// log error
// throw new MyException(result.error);
}
Normally you can't do much in this type of error so you log it, throw the exception and it's somebody's else problem. When the exception is caught, you could decide, based on the exception type, to wait and retry.

Who is invoking Error view and why?

I got a MVC4 web application running and functioning properly since almost a year. Lately while reviewing production error logs, I found a lot of mysterious exception entries of same type. I checked logs and found these exceptions occur on both Beta and Production environment but not in local (seems like a hint - see findings 1 below).
There are two subsequent entries:
One is:
Thread Id: 56, Message: Server_Exception - The view 'Error' or its
master was not found or no view engine supports the searched
locations. The following locations were searched:
~/Views/OrganizationUser/Error.cshtml
~/Views/OrganizationUser/Error.vbhtml ~/Views/Shared/Error.cshtml
~/Views/Shared/Error.vbhtml
Second log entry is:
Thread Id: 56, Message: Server_Exception - Stack Trace - at
System.Web.Mvc.ViewResult.FindView(ControllerContext context) at
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context)
at
System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.b__22(IAsyncResult
asyncResult) at
System.Web.Mvc.Controller.<>c__DisplayClass1d.b__18(IAsyncResult
asyncResult) at
System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult
ar) at System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult
asyncResult) at
System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult
ar) at
System.Web.Mvc.MvcHandler.<>c__DisplayClass8.b__3(IAsyncResult
asyncResult) at
System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass4.b__3(IAsyncResult
ar) at
System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step,
Boolean& completedSynchronously)
The exception is logged from Application_Error() in global.asax.cs like so:
var ex = Server.GetLastError();
if (ex != null)
{
logger.Log(string.Format("Server_Exception - {0}", ex.Message), LogCategory.Error);
logger.Log(string.Format("Server_Exception - Stack Trace - {0}", ex.StackTrace), LogCategory.Error);
}
And here is the snapshot of DB log messages:
Finding/Analysis:
Since the errors are logged only on remote server, it tells me it has got to do with how MVC handles remote errors? CustomErrors? - I don't have it defined it in web.config. Should I?
But the main question is, what caused the error to happen? And who is looking for view name Error? I know its hard for you to guess it but just checking my luck.
Another finding is the exceptions are logged after user has logged out. In my Login get form, I check isAuthenticated and if user is not authenticated I log a message 'Request not authenticated, showing login form.' and display login form. I can see this message in logged prior to above exception messages. So what's going on on login.cshtml that causes a contact to server which generates an error? I checked, login page and _Layout which has lots of server side code embedded but could not figure out what could cause server to try to load Error page.
I think internally MVC is calling Error page which does not exist in my source code hence these exception. But why 'Error' page? I thought to get advice on what to check in this case. Please advise if you want me to share anything that could help you understand my problem.
I suspect you are using the System.Web.Mvc.HandleErrorAttribute as this attribute will attempt to look for an Error view under certain conditions when an exception is thrown inside a controller action:
The currently executing action is not a child action
The exception has not already been handled or custom errors are enabled
When wrapped in a HttpException, the exception has a 500 HTTP status code
The exception is an instance of System.Exception
When all of the above are true, System.Web.Mvc.HandleErrorAttribute creates a System.Web.Mvc.HandleErrorInfo instance, sets the ExceptionContext.Result property to a ViewResult which by default has the ViewName property set to Error.
Putting all of this together, In one of your controllers, an exception must be being thrown that meets all of the above points, in a controller action that has the [HandleError] attribute applied (maybe it's applied globally), which is attempting to find the Error view and failing to do so.
To know what the original exception is, you could put an Error view into your solution and write out the Exception message of the HandleErrorInfo model instance passed to the view (if the current user has the appropriate access controls).

How to get Error code on custom error page

I have a common custom error page for my asp.net website because it's common it is shown on every error I want to found the last error code which was occurred and redirected to my that custom error page so that I can show right message according to the error which was occurred.
Note : solution have to be session based, I don't want any user to show error which was occurred on any other user's system of course.
Do you use IIS or Apache?
For Apache
Configuring Apache to serve customized error pages is extremely easy; there is a section of the httpd.conf file devoted to this. It takes just one directive per error to achieve. If you open the conf file and scroll right down to almost the very bottom of section two, you’ll see the section you need to edit.
By default, these directives are commented out, but all you need to do is un-comment each directive and then change the path to point to your own error page.
ErrorDocument 404 /errordocs/404error.html
For IIS
IIS 6: Edit Website or virtual Directory then Userdefinded Error.
There you can edit all error files and change to a user defined asp.net file.
IIS 7:
Detailed Error Message see:
http://blogs.msdn.com/b/rakkimk/archive/2007/05/25/iis7-how-to-enable-the-detailed-error-messages-for-the-website-while-browsed-from-for-the-client-browsers.aspx
Not good idea what you try to do. You must capture the errors on the code that they occur inside the page, and show the message on that page - stay on page - and if this is possible give the user the opportunity to correct it. If your error gets out of your try/catch and out of control then log it and fix it.
The only error that you can show to your user is the "non found page".
You can get the last error as Exception LastOneError = Server.GetLastError();
And there you can read more about errors: How do I make a "generic error" page in my ASP.NET application so that it handles errors triggered when serving that page itself?
and How to tell if an error captured by my global.asax was displayed on the screen of the user
What I would suggest is extending the UI.Page class and using that class for all your pages.
In that class (I know vb not c# but same principle and easy to convert) use the following code:
Public Class _PageBase
Inherits System.Web.UI.Page
#Region "Page Functions"
Private Sub Page_Error(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Error
Session("error_StackTrace") = Server.GetLastError.StackTrace.ToString
Session("error_Message") = Server.GetLastError.Message.ToString
Session("error_Page") = Request.Url.ToString
Session("error_Source") = Server.GetLastError.Source.ToString
Server.ClearError()
Response.Redirect("~/errors/Error.aspx")
End Sub
#End Region
End Class
This will fire on all pages using that base class, and pass the last 'server' error (which will be the error the user caused), store all the details in session and pass it over to your error page. Then you can do as you wish.

Categories