Q:

How to display friendly error message on page and cancel controller action

From a view 'x', when the user clicks on 'Edit Item', the Controller action that renders the 'Edit' page is also checking for the user's permissions to that page. 
What I'm trying to do is to check for those permissions and if the user does not have them, I would like to display an error message on that 'X' view and cancel the controller action.
Right now, my code looks like this:
 [HttpPost]
    public virtual ActionResult EditPage(int? itemId)
    {
        var model = new EditPageModel();
        if (itemId.HasValue)
        {
            var obj = new Item(itemId.Value);

   // Check for user's edit permission before we do anything else.

     var request = SecurityRequest.Create(obj, Item_Edit);
     Request.Execute(() => SecurityManager.ValidatePermissions(request));
            if (!request.IsValid(Item_Edit))
            {
                //skip the rest and return error
                Response.StatusCode = (int)HttpStatusCode.Forbidden;
                // Need Help Here!!!
            }

      // Mode code executes      
      return View(model);
    }

A:

One way you could do this (and this is an example of what I use in a current project) is to create your own ActionFilter. Here's my example:
public class UserAuthenticatedAction : FilterAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        if (IsContextFromLoginController(filterContext))
        {
            return;
        }

        //...Do whatever you need to check.

        if (userNotAllowed){
            SetRedirectToLoginErrorPageForContext(filterContext);
        }

        return;
    }

    private static void SetRedirectToLoginErrorPageForContext(AuthorizationContext filterContext)
    {
        filterContext.Result = new RedirectToRouteResult(
            new RouteValueDictionary
                {
                    { "controller", "Login" },
                    { "action", "LoginError" },
                    { "targeturl" , filterContext.RequestContext.HttpContext.Request.Url.ToString()} }
                });
    }

    private static bool IsContextFromLoginController(AuthorizationContext filterContext)
    {
        var controllerName = GetCurrentControllerName(filterContext);

        return controllerName.Equals("Login");
    }

    private static string GetCurrentControllerName(AuthorizationContext filterContext)
    {
        return filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
    }
}

To use this filter, in the global.asax.cs file, I have this line in Application_Start():
GlobalFilters.Filters.Add(new UserAuthenticatedAction(excludeActions, allowedRoles));
That means the attribute is executed whenever an ActionMethod is called. Basically it checks if the user is allowed to access a specific url and if that user is not allowed, then the filterContext is set to redirect them back to the login page.
I also check whether the current url is already the login page; if that's the case then don't bother doing the security check.
I guess there are more fancy ways of doing this, depending on your requirement, but the above method works fine for our needs. 

