Error.aspx /HandleError - asp.net-mvc

I am doing MVC 2
I have given HandleError attribute to all of my controller class.
I have
In my web.config
I also have Error.aspx in my shared folder of views.
Still on an exception in controller, The Error.aspx is not rendered

Steps:
Create a new ASP.NET MVC 2 project using the default template
throw new Exception(); inside the Index action of the HomeController.
Add in web.config: <customErrors mode="On" />
Hit Ctrl+F5 to run the project
The Error.aspx page is shown.

There are a lot of questions about this on StackOverflow because this is a tricky one with a lot of gotchas if you're not careful. From the sound of it, you need to set the HTTP Response to OK, otherwise the server will still render a generic 500 Error page because it still thinks the exception was not handled properly.
To do this, in your error view, add the following code:
#{
Response.StatusCode = (int)HttpStatusCode.OK;
}
Let us know if this works for you!
Edit: You also need to make sure that you have <customErrors mode="On"/> in the <System.Web> section of the web.config file at the root of your website.

Related

ELMAH IController factory not found - Right way to redirect to Error page - MVC

Am trying to use ELMAH with MVC4 and configured using NUGET Package for MVC.
It handles all the exceptions happening in my code and am logging it to SQL Server.
Using the Ajax Error function am handling AJAX Exceptions(500) Error too. Everything works fine and redirected Error page overriding OnException in Filter Config
But if the user changes the URL and and if the controller doesnt exist am getting Error and not redirected to the Error page.
Ex:
sitename/test -- Correct URL
sitename/tst ---- Getting Server Error instead redirecting to Error page
What is the correct way to handle 404 using ELMAH and redirecting to friendly 404 page in MVC.
I tried changing the Custom Error with 404 in web.config but it didn't worked as expected.
By default all Errors other than 404 am re directing to Error page
Am trying to redirect to friendly 404 page rather than server error page.
Any useful links or code will be helpful .Thanks
============================================
Update web.config
<customErrors mode="On">
<error statusCode="500" redirect="/Views/Shared/Error.cshtml"/>
<error statusCode="404" redirect="/Views/Shared/ErrorNotFound.cshtml"/>
</customErrors>
In ASP.NET MVC, your URL does not represent the View you are displaying. It is the Controller Action. You cannot navigate to a View.
For example, the url ~/Home/Index, does not point to Views/Home/Index.cshtml. It points to the Index method of Controllers/HomeController. This method then renders the Index.cshtml view and returns the result.
So first, you need to create an ErrorController. Then, you need to move your Error Views into a matching Error folder. Now add action methods for Error and ErrorNotFound to your ErrorController, and have them return the correct View.
Finally, change your web.config redirect URL's to ~/Error/ErrorNotFound.
Using this method, you will probably want to change the names of the Controller Actions, and their respective Views to remove the duplicated work Error.

Custom Error Page does not show even though I set CustomError="On"

I am using Visual Studio 2012 with the MVC 4 Framework and would like to see the friendly error page of the shared folder, if an exception is unhandled. (I know, as a develepor I need to see the error details but I just wanted to test this setting)
So far I know that adding the following code in the system.web section of web.config should do the trick
<customErrors mode="On" />
Unfortunately instead of my friendly error page I get this:
Server Error in '/' Application.
Runtime Error Description: An application error occurred on the
server. The current custom error settings for this application prevent
the details of the application error from being viewed.
Details: To enable the details of this specific error message to be
viewable on the local server machine, please create a
tag within a "web.config" configuration file located in the root
directory of the current web application. This tag
should then have its "mode" attribute set to "RemoteOnly". To enable
the details to be viewable on remote machines, please set "mode" to
"Off".
<!-- Web.Config Configuration File -->
<configuration>
<system.web>
<customErrors mode="RemoteOnly"/>
</system.web> </configuration>
Notes: The current error page you are seeing can be replaced by a
custom error page by modifying the "defaultRedirect" attribute of the
application's configuration tag to point to a custom
error page URL.
<!-- Web.Config Configuration File -->
<configuration>
<system.web>
<customErrors mode="On" defaultRedirect="mycustompage.htm"/>
</system.web> </configuration>
I would like to do it as described and not with a workaround like adding an action to HomeController, setting routes or something.
A reference that this should work is the following:
http://pluralsight.com/training/players/PSODPlayer?author=scott-allen&name=mvc3-building-controllers&mode=live&clip=0&course=aspdotnet-mvc3-intro
(On left select the chapter "Action Filters" and skip to minute 3:30)
UPDATE (link changed):
http://pluralsight.com/training/Player?author=scott-allen&name=mvc4-building-m2-controllers&mode=live&clip=0&course=mvc4-building
(On top click on the thin line that states "Controller in ASP.NET MVC 4", then click on "Action Filters" and skip to minute 5:00)
Does anybody have a clue why I cannot see the friendly error page with the setting mentioned above?
Thanks in advance!
Here is step by step guide to doing this,
To start with, first set the “customErrors’s” mode property to ‘on’. (This specifies that custom errors are enabled.)
1. Code from Web.config
<system.web>
<customErrors mode="On"></customErrors>
</system.web>
Below is my controller code, I have specified the HandleError attribute on the controller class. Also to generate an error I am throwing an exception from the Index action.
2. Code from HomeController.cs
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
throw new Exception("Error Occured !");
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
return View();
}
}
As you can see in the screenshot below, I have a Error.cshtml view defined inside the Shared folder of the Views folder.
3. Solution Explorer
Note that the Error.cshtml view (shown below) uses a model of ‘System.Web.Mvc.HandleErrorInfo’
4. Code from Error.cshtml
#model System.Web.Mvc.HandleErrorInfo
#{
ViewBag.Title = "Error";
}
<h2>
Sorry, an error occurred while processing your request.
</h2>
On running the project, instead of getting the yellow death screen now I get the following output.
Taken from this article
Update :
Try this out by creating a new project, this should and does work. I suspect that your Error.cshtml file may not have model as #model System.Web.Mvc.HandleErrorInfo or you may be having multiple Error.cshtml pages in different view folders.
I fixed mine.. It's actually the *_Layout* page cannot be rendered because my _Layout.cshtml was strongly typed to a base view model which HandleErrorInfo can't be casted into. And you can never see this page binding error because it only happens when customError is on... that's just great.
One reason that could lead to what you are experiencing:
Something in your _layout is causing an exception to throw when the 'Error.cshtml' is rendering.
Do a test adding
#{
Layout = null;
}
in your 'Error.cshtml' file.
I had the same problem when I was updating the wrong web.config file.
There is a web.config in the Views folder and also under the project application site.
The solution would be to update web.config located under project.
This does not work with Visual Studio Express Edition. It works if you are using Professional or Ultimate Edition of Visual Studio IDE.

Invoke ASP.NET MVC Controller When Requesting .html file

I need to add some new life to a legacy application :)
I'd like to call an MVC controller when a "static" HTML page is requested in order to add some markup to the page before returning it to the client.
I tried to follow the approach found in this thread: How to read web.config settings in .html page?
...but even though I have this route defined:
routes.MapRoute(
name: "Topic",
url: "html/{fileName}.html",
defaults: new { controller = "Topic", action = "Index" });
the controller is not being called. I have my web.config defined with:
<remove name="WebServiceHandlerFactory-Integrated" />
<add name="HTML" path="*.html" verb="*"
type="System.Web.UI.PageHandlerFactory"
resourceType="File" preCondition="integratedMode" />
I suspect that I need to call something else besides the PageHandlerFactory or perhaps the issue is something entirely different.
UPDATE: My dev environment is working with integrated pipeline mode, but I need to check if my production environment will support it.
If you do this:
routes.RouteExistingFiles = true;
You should find this works - even without the handler addition. In the controller you can load the HTML directly using the HostingEnvironment.VirtualPathProvider's GetFile method and do something with it - or better still just use a normal MVC view that renders the same content as the static file, just with your additions.
Although be aware that this means any files that are potentially caught by any routes will be pushed into the MVC pipeline. This isn't generally a concern, however, if decent separation of routes and physical paths is used.
I setup the same situation as you and it worked well for me, so you have the key components in place. Some things to keep in mind for the testing and troubleshooting:
Your web.config does need the build provider for the html extension:
<system.web>
<compilation>
<buildProviders>
<add extension=".html"
type="System.Web.Compilation.PageBuildProvider" />
</buildProviders>
</compilation>
</system.web>
A copy and paste of your handlers works for me, so that looks good.
And a copy and paste of your MapRoute works for me too, although I used the default Home controller in a clean project. So as a double check just confirm that you have a controller called Topic with an ActionResult method called Index().
And make sure that your url is localhost.com:{port}/html/test.html with the /html/ in the path since your rule asks for that.
Another good test is to change your MapRoute to use aspx instead and test an aspx page and see if that works. That will confirm whether or not it's the IIS mappings or if it's the MVC rules. If it works with aspx then the issue is related to the handler, but if it fails with aspx too then it's something with MVC.
Also confirm that you're using IIS Express and not Cassini. Cassini will not handle that correctly, but IIS Express will. You can confirm by right-clicking on your project and you should see a menu option called "Use Visual Studio Development Studio...". That will only exist if you are currently using IIS Express.

Redirect to Error page in mvc

I working in mvc 2 and need to redirect on error page with exception mesage.
For this I have i have override OnException () action of controller
and trying to do like " View("Error").ExecuteResult(this.ControllerContext);"
but it is throwig exception 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper"
please give me the right solution
Regards Munish
The HandleError attribute redirects to the Error page that is placed in the shared folder. This page has a model of type System.Web.Mvc.HandleErrorInfo which contains an Exception property. You should modify the Error page so that it displays the exception information you want, like for example <%:Model.Exception.Message %>.
Also make sure that you have the <customErrors mode="On" /> inside the <system.web> in the web.config file otherwise, during development the HandleErrorAttribute won´t intercept the exceptions.
Good luck!

attribute does not seem to act at all

I am having problems using the [HandleError] attribute on my Controller Actions - it doesn't seem to work at all (i.e. it doesn't matter if the filter is there or not - I get the same results...). When an Exception is thrown, I get the standard red-toned Server Error in '/' Application error page instead of my custom view.
I have found a couple of other threads on the subject here on SO, and in most cases it seems that setting the customErrors option to On in web.config solved the problem. It has not for me, so I need to find a different solution.
My controller action:
[HandleError]
public ActionResult Index()
{
throw new Exception("oops...");
return View();
}
In my web.config file
<customErrors mode="On"></customErrors>
I have made sure that the Error.aspx file is in the Shared directory, too. What am I missing?
I am running ASP.NET MVC RC Refresh.
Two useful things to know:
By default, HandleError does nothing when running under the development server. The intention is to show developers more useful information:
public virtual void OnException(ExceptionContext filterContext) {
if (filterContext == null) {
throw new ArgumentNullException("filterContext");
}
// If custom errors are disabled, we need to let the normal ASP.NET
// exception handler execute so that the user can see useful
// debugging information.
if (filterContext.ExceptionHandled
|| ! filterContext.HttpContext.IsCustomErrorEnabled) {
return;
}
Note that this case is precisely what customError is supposed to control. If setting customError="On" does not change this behavior:
Check your syntax.
Make sure you're editing the Web.config in the project root, not the one in Views.
Make sure no code sets HttpContext.IsCustomErrorEnabled.
If all else fails, try turning debug off in Web.config
Second, there certain types of errors which HandleError will never handle, notably ASP.NET compilation errors. You don't say which error you're encountering.
You need to specify what page to redirect to as well.
<customErrors mode="On" defaultRedirect="Error.aspx" />
EDIT: Sorry the /Shared/ part should not bet there but you need to tell MVC which page to send the user to with Error.aspx. Then the default route looks for something called Error.aspx in shared.
It was very late! :) I guess that's why someone gave me a minus for the answer! :) At least it works here mate!
I got the same issue and it took me two full days to figure it out finally. It turned out to be that I got an error in Site.Master page, and the Error.aspx used this same master page as all other pages. Obviously the Error.aspx couldn't deal with such situation.
My solution is to create a specific Error.master page that is lightweight and does not include any model data. Additionaly I created a static Error.htm in case an error occurs from Error.aspx. The Web.config setting is as follows:
<customErrors mode="On">
<error statusCode="500" redirect="Error.htm" />
</customErrors>
Hope it helps.
Another reason for this problem may be ,
In Template MVC Application (generated by VS2008 / VS2008 Express) , Error.aspx (generated by VS) uses Master Page.
If Master Page access any ViewData it will throw null reference Exception , then the error.aspx won't be shown.
Use this Simple code as your Error.aspx , it will solve the problem, (along with CustomErrors=On )
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<System.Web.Mvc.HandleErrorInfo>" %>
<%= Model.Exception.Message %>
To get around the 404 problem when the Error.aspx was supposed to be shown, I had to exclude the Error.aspx from the httpHandler section which prevented any views from being accessed directly (around the mvc 2 framework). I did this by putting Error.aspx in an 'Error' subfolder and putting a web.config in this subfolder with a
<remove path="*" verb="*" />
in the httpHandlers section. My version of this problem (and its solution) may be specific to MVC 2.
Remember to update the defaultRedirect reference, when you move Error.aspx :)
I tried the above suggestions but nothing worked for me. What did the trick was removing this line from my actions within my error controller.
Response.StatusCode = (int)HttpStatusCode.NotFound;
I was pulling my hair out since IIS error messages kept intercepting my error handling. And while its not ideal since I want to provide that status code in my response, I found that removing it prevented IIS 7+ from interfering with my error handling.
DaTribe

Resources