Gayan
Gayan

Reputation: 2871

Update view when 404 exception

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

Answers (3)

Rush Frisby
Rush Frisby

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

Sreejan
Sreejan

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

NightOwl888
NightOwl888

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

Related Questions