title: Redirect to "You Are Forbidden" page without changing URL ASP.NET MVC
body: <p>I set up a custom Authorization Attribute in my project to do some checks on a user's permissions. If they aren't allowed to do a certain activity, they get redirected to a "You Are Forbidden" page via <code>RedirectToRouteResult</code>. However, I would like to make this function without changing the URL so the user can refresh the page if they receive permission. Is this possible?</p>
  
  <p>How I'm doing it currently. It sends to the URL <code>Forbidden/</code>.</p>
  
  <pre><code>[AttributeUsage(AttributeTargets.Method)]
  public class AuthActivityAttribute : ActionFilterAttribute
  {
      public string ActivityName { get; set; }
      public int ActivityId = 0;
  
      public override void OnActionExecuting(ActionExecutingContext filterContext)
      {
          if (!ViewIsAuthorizedActivity(ActivityName))
          {
              filterContext.Result = Forbid();
              base.OnActionExecuting(filterContext);
          }
      }
  
      public RedirectToRouteResult Forbid()
      {
          return new RedirectToRouteResult(
              new RouteValueDictionary
                  {
                      { "controller", "Home" },
                      { "action", "Forbidden" },
                      { "Activity", ActivityId },
                      { "area", ""}
                  });
      }
      // other stuff
  }
  </code></pre>
  
  <p>Edit / Solution:</p>
  
  <p>I ended up using a combination of rendering <code>PartialView</code> for GET Requests and <code>RedirectToRouteResult</code> for POST Requests. I chose this for two reasons: </p>
  
  <ol>
  <li><p>The user has the page loaded before losing permission, therefore the Forbidden partial view isn't loaded.  Without the <code>RedirectToRouteResult</code> on POSTs, they could POST even though they don't have permission.</p></li>
  <li><p>Someone could attempt to over post the page and have some success if they hit some Included values.</p></li>
  </ol>
  
  <p>Attribute:</p>
  
  <pre><code>public override void OnActionExecuting(ActionExecutingContext filterContext)
  {
      if (!ViewIsAuthorizedActivity(ActivityName))
      {
          string requestMethod = filterContext.HttpContext.Request.HttpMethod;
  
          if (requestMethod == "GET")
          {
              filterContext.Controller.ViewBag.Authorization = "FORBIDDEN";
          }
          else if (requestMethod == "POST")
          {
              filterContext.Result = new RedirectToRouteResult(
              new RouteValueDictionary
                  {
                      { "controller", "Foo" },
                      { "action", "Bar" },
                      { "area", ""}
                  });
          }
  
          base.OnActionExecuting(filterContext);
      }
  }
  </code></pre>
  
  <p>View:</p>
  
  <pre><code>@if (ViewBag.Authorization == "FORBIDDEN")
  {
      ViewBag.Title = "Forbidden!";
      @Html.Partial("~/Views/Home/Forbidden.cshtml");
  }
  else
  {
      &lt;!-- Page --&gt;
  }
  </code></pre>