I am sick of the asp.net, just one question that
//EmpService.cs
Emplee emp = loadDataFromDB(emp_id);
if (emp == null) //Fail to get employee data
{
this.custom404();
}
Based on the MVC framework, how do we handle the custom404 and finally return a custom 404 Not Found page to the user? Like how to define controllers, how to define views. A concrete example with codes would be better. Thanks!
In the web.config file place these code inside <system.web></system.web> and create Error controller and three actions Error404 etc. and respective view pages. if iis returns status 500 then the Error404 page will be shown. You can create your own error pages.
<customErrors mode="On" defaultRedirect="Error">
<error statusCode="404" redirect="~/Error/Error404" />
</customErrors>
Related
I'm attempting to create custom 403 error page that will display the status description from the error.
I'm using the following code to trigger the 403 error
from both Controllers and Action Filters
Controller Call
return new HttpStatusCodeResult(HttpStatusCode.Forbidden,
"String_Of_Why_This_Request_is_Forbiden")
Actionfilter Call
filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden,
"String_Of_Why_This_Request_is_Forbiden")
Both of these get redirected to my Custom 403 error page.
but as the request passes through my Web config and errors controller I lose both the HTTP status code and the status description.
Web.Config
<httpErrors errorMode="Custom" existingResponse="Auto">
<remove statusCode="403" subStatusCode="0" />
<error statusCode="403" subStatusCode="0" path="/Error/Forbidden" responseMode="ExecuteURL" />
</httpErrors>
ErrorControllerAction
public ViewResult Forbidden(string errorMessage)
{
Response.StatusCode = 403;
return View("Forbidden", errorMessage);
}
My assumption is that my current handling is simply generating a new request via my errors controller.
Question
How can I do this in such a way that I can pass the Original Status Description through the Errors Controller to my View?
Well you can redirect to you controller action and pass in the error message instead.
Here's a good general article for custom error page in ASP.NET MVC
https://www.c-sharpcorner.com/UploadFile/618722/custom-error-page-in-Asp-Net-mvc/
In my global.asax file, I have the following code:
void Application_Error(object sender, EventArgs e)
{
Exception TheError = Server.GetLastError();
if (TheError is HttpException && ((HttpException)TheError).GetHttpCode() == 404)
{
Response.Redirect("~/404.aspx");
}
else
{
Response.Redirect("~/500.aspx");
}
}
When I navigate to an non-existing page, I get the generic error page. I don't want anything pertaining to custom error in the web.config because my plan is to add code to the global.asax file to log the exceptions. Is there a way to handle custom error with just the global.asax file?
EDIT:
The answer is not obvious, but this seems to explain it: http://www.asp.net/web-forms/tutorials/deployment/deploying-web-site-projects/displaying-a-custom-error-page-cs
If you scroll down a ways, you'll find this lovely tidbit:
Note: The custom error page is only displayed when a request is made
to a resource handled by the ASP.NET engine. As we discussed in the
Core Differences Between IIS and the ASP.NET Development Server
tutorial , the web server may handle certain requests itself. By
default, the IIS web server processes requests for static content like
images and HTML files without invoking the ASP.NET engine.
Consequently, if the user requests a non-existent image file they will
get back IIS's default 404 error message rather than ASP.NET's
configured error page.
I've emphasized the first line. I tested this out in the default template, and sure enough, this URL:
http://localhost:49320/fkljflkfjelk
gets you the default IIS page, whereas simply appending a .aspx makes the Application_Error kick in. So, it sounds like you need to enable customErrors/httpErrors if you want to have all errors handled.
For IIS <= 6, add to <system.web>:
<customErrors mode="On" redirectMode="ResponseRewrite">
<error statusCode="404" redirect="/404.aspx"/>
<error statusCode="500" redirect="/500.aspx"/>
</customErrors>
For IIS7+, add to <system.webServer>:
<httpErrors errorMode="Custom">
<remove statusCode="404"/>
<error statusCode="404" path="/404.aspx" responseMode="ExecuteURL"/>
<remove statusCode="500"/>
<error statusCode="500" path="/500.aspx" responseMode="ExecuteURL"/>
</httpErrors>
I'll leave the original answer in case someone finds it useful.
I believe you need to clear the existing error code from the response, otherwise IIS ignores your redirect in favor of handling the error. There's also a Boolean flag, TrySkipIisCustomErrors, you can set for newer versions of IIS (7+).
So, something like this:
void Application_Error(object sender, EventArgs e)
{
Exception TheError = Server.GetLastError();
Server.ClearError();
// Avoid IIS7 getting in the middle
Response.TrySkipIisCustomErrors = true;
if (TheError is HttpException && ((HttpException)TheError).GetHttpCode() == 404)
{
Response.Redirect("~/404.aspx");
}
else
{
Response.Redirect("~/500.aspx");
}
}
Looks like IIS is looking for a page and did not find it.
Make sure:
404.aspx is created
customErrors tag from web.config is not present.
I'm trying to understand HandleErrorAttribute in MVC3. (I also followed old article from ScottGu) I added the <customErrors mode="On" /> to the web.config file. All errors redirect to the \Views\Shared\Error.cshtml view. If I keep the HandleErrorAttribute or remove from the controller, there is no difference in the behavior.
Code of the controller
public class HomeController : Controller
{
[HandleError]
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
throw new Exception();
return View();
}
}
Also, I show in some articles and SO post, that with <error redirect="..."/>, request can be redirected to the required view.
Qestions
What is the use of HandleErrorAttribute?
What is the advantage of using it over <customErrors.. ?
What can we achieve that is not achievable by <customErrors.. ?
1) The HandleErrorAttribute (MSDN) is a FilterAttribute that is used to handle controller actions that throw an error. I would suggest reading the documentation on the MSDN page as it describes exactly what it does and the constructors that it can take. Additionally in your webconfig you must have the customErrors section set to.
<system.web>
<customErrors mode="On" defaultRedirect="Error" />
</system.web>
2) Now the custom errors section is used to allow the Asp.Net application to control the behavior of the page when an error (Exception) is raised. (MSDN) When the custom Errors is set to On or RemoteOnly when an application exception happens the application will use the rules defined in the Web.config to either display the error message or redirect to a page.
3) Using the HandleErrorAttribute you can provide different redirections \ views based on the exception types raised.
I would recommend you view this SO topic for more information (read Elijah Manor's post). ASP.NET MVC HandleError
Cheers.
Im using a CMS product called EPiServer. We need to create our own method of displaying 404's which just can't be achieved using .NET's standard customErrors. We've writen a module which we use to check for the HttpStatusCode. We do this in the EndRequest method.
If the status is 404, we query EPiServer for the appropriate 404 page, and then Transfer the request over to that page. However this doesnt return a 404, and even if I do the following the correct status isnt returned:
HttpContext.Current.Response.StatusCode = 404;
HttpContext.Current.Response.StatusDescription = "Page not Found";
HttpContext.Current.Server.TransferRequest(newPage);
Likewise, if I do a response.redirect instead of a TransferRequest then its not a proper 404 because the url has then changed...
Whats the right way of doing this?
Thanks in advance
Al
Not a direct answer to your question but could also take a look at this open source 404 handler: https://www.coderesort.com/p/epicode/wiki/404Handler
It is also available on episervers nuget feed
Which IIS version are you using? For IIS7 or 7.5 you might need something like this:
<httpErrors errorMode="Custom">
<remove statusCode="404" />
<error statusCode="404" path="/somenotfoundpage.aspx" responseMode="ExecuteURL" />
<remove statusCode="500" />
<error statusCode="500" path="/someerrorpage.aspx" responseMode="ExecuteURL" />
</httpErrors>
You should set the status code in the codebehind of the template you're using for your 404 page.
If this is a plain content page, either create a new template or add a Status Code property to the page and logic in the code behind to send the appropriate header if this is not null or empty.
Try setting the status code on the page that you transfer to - in your error page template. I'm not sure that having a separate module is necessary - you can simply handle the HttpApplication's Error event in Global.asax.cs.
Thanks for your responses.
I actually got this working by doing the following:
In the EndRequest event handler I transferred the request off to the correct EPiServer page, and included a querystring param in the call i.e.
app.Context.Server.TransferRequest(pageUrl + "&internal=true");
Then in the PostRequestHandlerExecute event I check for the querystring param, if it exists it can only be because it's a 404 so I return the correct status:
HttpContext.Current.Response.StatusCode = 404;
HttpContext.Current.Response.StatusDescription = "Page not Found";
Works like a charm.
Thanks
higgsy
I have set up custom error pages on my site using
<customErrors mode="RemoteOnly" defaultRedirect="~/Error">
<error statusCode="500" redirect="~/Error/InternalError"/>
<error statusCode="404" redirect="~/Error/FileNotFound"/>
<error statusCode="403" redirect="~/Error/AccessDenied"/>
</customErrors>
however there is another area on the site, Suppliers, and when an error occurs in the supplier area the redirect goes to Suppliers/Error/_. Since I don't have any error pages here, the site just seems to hang never shows the error pages. How can I fix this without having to copy the error pages to the supplier area?
As far as I understand with MVC your URL make up, by default is:
Domain/Controller/Action/id
If you have an "Error" Controller. In your logic, you test to see if the request originated from an user of the site that would need to redirect to the "Suppliers" Error page
[HandleError]
public ActionResult Index()
{
// Test to see if you need to go to the SuppliersController
if (this.User.IsInRole("supplier"))
{
return Redirect("/Suppliers/Error");
}
else
{
return View(); // This returns the "Error" View from the shared folder
}
}
redirect to an Error handling action on your Suppliers Controller that will return the right view.
public class SuppliersController : Controller
{
//
// GET: /Suppliers/
public ActionResult Error()
{
return View("Error","SomeMasterPage"); // No "Error" view in Suppliers View folder, so it uses the one in shared folder
}
}
You can also use the [Authorize] attribute on your Suppliers Error Action to make sure the user is logged on.
In this way, you will get your desired /Suppliers/Error URL and can use the SuppliersController Action to specify the desired view, model, and master/Layout page.
also look at this very comprehensive reply to a similar question:
Best 404 example I can find for mvc
I guess removing the "~" before the error page should do the trick, you will need the "\" though.
Another way would be to write the FULL URL in the redirect/defaultRedirect attribute.