Reputation: 2871
On my code i'm using log4net to log exception and end of the logging i want to update view with proper message view. on my log service update view (actually my code does redirect) my code look like this
private readonly HttpContextBase _httpContext;
public void RedirectToError()
{
var httpException = _httpContext.Server.GetLastError();
if (httpException != null && (_httpContext.Server.GetLastError() is HttpException))
{
_httpContext.Server.ClearError();
_httpContext.Response.Redirect("/Error", false);
}
}
but i actually wants to update the viewresult only like authorized attribute i able to update the viewresult like this
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new ViewResult {ViewName = "NoPermissions"};
}
else
{
// let the base implementation redirect the user
base.HandleUnauthorizedRequest(filterContext);
}
}
but nor like filtercontext, how can we update viewresult with httpcontext? if no way to do that with httpcontext how could we achieve this ?
Thanks
Upvotes: 4
Views: 249
Reputation: 11454
It looks like you're trying to avoid the 302 before the displaying the error page and just return a 404 with the error...
If you get to a controller method that is returning a ViewResult then you're already past the point at which ASP.NET has determined that it should return a 404 or not.
For 404's in MVC I would use this answer.
Upvotes: 0
Reputation: 36
You can catch the error in the Application_Error Method in the Global.asax and use the HttpContext to redirect to your page.
Protected void Application_Error(object sender, EventArgs e)
{
MvcApplication app = (MvcApplication)sender;
HttpContext context = app.Context;
Exception exc = Server.GetLastError();
if (exc.GetType() == typeof(HttpException))
{
errorCode = ((HttpException)exc).GetHttpCode();
}
else if (exc.GetType() == typeof(Exception))
{
errorCode = 500;
}
var routeData = new RouteData();
routeData.Values["controller"] = "{Your Controller}";
routeData.Values["statusDescription"] = "{Your Description}";
routeData.Values["action"] = "http500";
switch (errorCode)
{
case 404:
Server.ClearError();
routeData.Values["action"] = "Your action name";
break;
case 403:
Server.ClearError();
routeData.Values["action"] = "Your action name";
break;
case 405:
Server.ClearError();
routeData.Values["action"] = "Your action name";
break;
case 500:
Server.ClearError();
routeData.Values["action"] = "Your action name";
break;
default:
Server.ClearError();
routeData.Values["action"] = "Your action name";
break;
}
IController controller = new ErrorsController();
controller.Execute(new RequestContext(new HttpContextWrapper(context), routeData));
Server.ClearError();
}
Please respond if it helps. :)
Upvotes: 0
Reputation: 56869
It is unclear where the first block of code is and whether the second block even relates to your question (other than a demo). Your question is unclear, so this is a shot in the dark.
One way to pass information from one part of the application to another is to use request caching.
private readonly HttpContextBase _httpContext;
public void RedirectToError()
{
var httpException = _httpContext.Server.GetLastError();
if (httpException != null && (_httpContext.Server.GetLastError() is HttpException))
{
_httpContext.Server.ClearError();
// Store the error in the request cache
_httpContext.Items["LastError"] = httpException;
_httpContext.Response.Redirect("/Error", false);
}
}
Then in your Error action method you can access this value.
public ActionResult Error()
{
// Retrieve the error from the request cache
Exception lastError = (Exception)this.HttpContext.Items["lastError"];
// Pass the error message to the view
ViewBag.Error = lastError.Message;
return View();
}
Typically, you would just log the error and not show it to the user because of the security implications that can have.
Upvotes: 1