WebMethod not returning Exception data - asp.net

Doing an $.Ajax() POST call to a WebMethod in a WebForms WebSite application. The calls work fine, except for when exceptions occur in the WebMethod. They are not passed down. From the WebMethod, the $.Ajax call returns an xdr.responseJson object with ExceptionType, Message, and StackTrace attributes. This is where I would expect to find the exception info but instead, no matter what the exception is on the server, ExceptionType returns "", Message is always "There was an error processing the request." and the StackTrace is "". What needs to be done for these to be populated with meaningful data from the server?

I ended up solving this by changing the web.config:
<customErrors mode="Off" />
After that change, Message, ExceptionType, and Stack trace became properly populated instead of the standard "There was an error processing the request." which gets returned for all exceptions when mode=on and is not very helpful for debugging or reporting.
Wish this setting was more granular so I could turn it off only for WebMethods.

Related

Event Viewer spammed with event 1309 (HttpException) due to illegal URL from IIS ASP.NET website

I host a website that provides public API access for my customers to track their orders with an order number. I have allowed them to use both POST or GET (with URI parameter) to pass the order number to me. Some of them however wrote careless codes that passes illegal chars (asterisk, colon or incorrectly encoded asian characters), like this https://mycompany.com/tracking/orderno:ODR12345 which causes IIS to throw exception:
Exception information:
Exception type: HttpException
Exception message: A potentially dangerous Request.Path value was detected from the client (:).
at System.Web.HttpRequest.ValidateInputIfRequiredByConfig()
at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)
I have inherited Application_Error method to log this exception. But it still gets thrown as a 400 Bad Request error to user browser and leave an Event 1309 in my event viewer, hence spamming the log with it.
I know I can turn off illegal-chars-exam from Web.config universally but that's a security risk. I just want to be able to handle this exception myself: capture it, log it my own way, provide useful response to user and then suppress it so it doesn't pollute my system log. How can I do this?
UPDATE
Lex gave me an idea to rewrite the URL. What I think is, I can put the parameter into the query string instead of leaving it a part of the path, so that dangerous path error will disappear. I then wrote the following rule:
<rule name="TrackingRewrite" enabled="true" stopProcessing="true">
<match url="/tracking/(.*)" />
<action type="Rewrite" url="tracking?querystring={R:1}" />
</rule>
So that https://mycompany.com/tracking/orderno:ODR12345 becomes https://mycompany.com/tracking?querystring=orderno:ODR12345 and the correct action was executed and users gets a 200 response with tracking information. However - after the controller action returned, Applciation_Error call back still gets called with the "A potentially dangerous Request.Path value was detected from the client (:)." exception and system log was added. Breaking into the Applciation_Error call back and printing the Request.Url shows the original illegal URL, not the rewritten one. How does one to comprehend this behavior?

Sending binary data though POST

I'm using system.text.utf8encoding.utf8.getstring to convert a byte array to a string and then am sending it to my asp.net program through a regular web request as a POST value. Every now and then, I get an exception
"A potentially dangerous Request.Form value was detected from the
client "
Is it possible to get rid of that?
EDIT: never mind, I started using webclient.uploaddata to send and receiving by request.binaryread instead, this method doesn't seem to have this problem.
try to Add below code put to your web.config file.
<system.web>
<pages validateRequest="false" />
</system.web>

An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page

Server Error in '/' Application.
Runtime Error
Description: An exception occurred while processing your request. Additionally, another exception occurred while executing the custom error page for the first exception. The request has been terminated.
The above error occurs now and then on my PROD. Recycling the application pool resolves the issue but after few days the same error resurfaces again. I did browse through other post relavant to this topic but it seems this error occurs always for them which is not same for me.
There is a server error on your error page, so the error page tries to redirect to the error page. To avoid an infinite loop, the request is terminated.
Use an HTML error page, rather than a .ASPX page.
Disabling custom errors will also 'fix' this, but, you don't want to do that on production.
You can also use ELMAH to log exceptions and then fix the issue.
<system.web>
<customErrors mode="Off" />
</system.web>

ASP.NET Common Error Page Best Practises

I am working on an ASP.NET web application. I am implementing the logging framework for the entire application.
web application has around 7-8 pages and is a simple CRUD operations web application.
Its an Azure hosted application. Following is the approach i am following for logging and exception handling.
1) Added Try...Catch blocks in the Data Access Layer, and Click events.
2) Upon catching errors, I am propagating the exceptions upto the Globabl.asax leve, and in Application_Error event logging the error into Event Logs and Trace Logs.
3) After this in the Global.asax file I am Redirecting to an Error Page to show a User Friendly Message and link to the failed page.
4) Just wanted to know whether is it a good approach to do this.
Thanks Friends.
Are you actually handling exceptions on the DAL (ie, logging, trying to fix it, etc)? If not, then the try catch serves no purpose other than spinning cycles. The same is true for the click events, but it is not a bad practice to handle errors on the UI, even if you are not truly doing anything with them, as you will divert the user from the ugly error page to your own friendly message.
A single error page works fine, if you truly cannot handle the exception thrown. The upside is time to market, as you write precious little code to avoid showing the user an ugly message. The downside is the user misses context. I am not really up on the one size fits all exception handler, except as a backup (have an error I did not envision that got past my first line handler).
There is a variation of the common error page, if you are handling based on HTTP statuses and that is to use config.
Another pattern is to set up your own base page and have it work as an error handler. You can then set aside a container to fill when an error occurs. This approach works nicely for adding context, as the user still sees part of the page he was on, but you have given an error message, so he knows things have failed. I have seent this pattern used with a user control that is added to the container when an error occurs, but this is a bit more invovled, as you have to set up a table of codes and proper messages to show (which can be buggy in and of itself).
Why not using ASP.NET custom error pages ? You can specify each error page for each status code or you can specify a default redirect.
You can configure this in the web config and you are all set.
<customErrors defaultRedirect="GenericError.htm" mode="On">
<error statusCode="404" redirect="notfound.htm"/>
</customErrors>
You can configure it for showing the custom error pages to all users or only to remote users etc..
http://aspnetresources.com/articles/CustomErrorPages
I totally agree that you should log all errors in your catch block and write it to a log.
It sounds like you're kind of reinventing the wheel here. ASP.NET already includes things to help you achieve the desired result. Unless you need handling logic to cleanup after the errors, I wouldn't use try catch blocks. Have a look at the ASP.NET Health Monitoring Overview for logging errors. As far as presenting a custom error page see How to create custom error reporting pages in ASP.NET by using Visual C# .NET.
I think, You need not to use Exception Handling. Suppose You have a Presentation Layer and a Business Logic Layer/DataAccess Layer.
Upon facing the error in say Business Logic, it will move directly to Glogal.asax.cs file under Application_Error Event without going back to the calling function. Here you can log the error message like below....
HttpContext.Current.Server.GetLastError().InnerException.StackTrace
HttpContext.Current.Server.GetLastError().InnerException.Message
HttpContext.Current.Server.GetLastError().InnerException.Source
HttpContext.Current.Server.GetLastError().InnerException.TargetSite.DeclaringType.FullName
HttpContext.Current.Server.GetLastError().InnerException.TargetSite.DeclaringType.Name
HttpContext.Current.Server.GetLastError().InnerException.TargetSite.DeclaringType.Namespace
Now in the Web Config you can write code to redirect the user on some default page like below.
<customErrors defaultRedirect="ErrorPage.htm" mode="On">
<error statusCode="404" redirect="ErrorPageNotFound.htm"/>
</customErrors>

How to handle exceptions during an ASP.NET request lifecycle

This question is kind of related to Handle URI hacking gracefully in ASP.NET in that it's too about how to best handle exceptions that occur during an ASP.NET request lifecycle. I've found a way to handle most exceptions gracefully, but then I've found that some exceptions occur so late in the request that there's no way to do stuff like Server.Transfer to compartementalize the whole error presentation logic into its own page.
So, I have to handle the exception inside the Application_Error event instead, and do Response.Writes and whatnot. It's ugly. I understand that in some circumstances the response stream could have already been flushed, so transferring the request isn't really an option. What I want to ask is if there's anyone who's found an elegant solution to this problem?
Also, I find it difficult to know when I can handle the exception gracefully by transferring the request to another page and not. What is the best way to find out where in the request lifecycle we're at when an exception occurs? If it occurs during the loading and rendering of a page, Page_Error will be able to handle it and I've not had a problem doing Server.Transfer there yet. But if the exception occurs either too early or too late for Page_Error to catch it and it bubbles to Application_Error, what do I do to know whether it's early or late?
If it's late in the lifecycle, I'll probably have to do Response.Write directly from Application_Error, but if it's early I can do Server.Transfer. The problem is that trying to do Server.Transfer will itself cause an exception if it's too in the request to do it.
So, is there a global enumeration or something similar that will indicate whether it's too late to do creative stuff with the response or not?
I have used this approach to catch all errors generated, either in web controls or pages. All it requires you to do is to inherit from a base class (one for pages and one for usercontrols) each page or usercontrol can implement its own HandleException method and do whatever it needs to do.
Full code here:
Transparent generic exception handling for asp.net / MOSS2007 (with code)
I think my advice for this would be to use ASP.NET Health Monitoring with WMI Events provider for the errors:
Here is a how to.
http://msdn.microsoft.com/en-us/library/ms178713.aspx
Hope this helps:
Andrew
I suggest that you use asp.net configuration to have a general error page for the unhandled exceptions. From the sample web.config
<!--
The <customErrors> section enables configuration
of what to do if/when an unhandled error occurs
during the execution of a request. Specifically,
it enables developers to configure html error pages
to be displayed in place of a error stack trace.
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
<error statusCode="403" redirect="NoAccess.htm" />
<error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>
-->
On the overall handler, just log the exception, and let asp.net do the redirect.
If you still want to go on with your customer approach, I suggest you look at the available asp.net source and check how it is doing that.

Resources