如何在页面上显示友好的错误消息并取消控制器操作

时间:2012-05-18 15:18:29

标签: c# asp.net-mvc asp.net-mvc-3 controller

从视图“x”开始,当用户点击“编辑项目”时,呈现“编辑”页面的Controller操作也会检查用户对该页面的权限。

我要做的是检查这些权限,如果用户没有,我想在“X”视图上显示错误消息并取消控制器操作。

现在,我的代码看起来像这样:

 [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);
    }

3 个答案:

答案 0 :(得分:1)

您可以这样做的一种方式(这是我在当前项目中使用的示例)是创建您自己的ActionFilter。这是我的例子:

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;
    }
}

要使用此过滤器,请在global.asax.cs文件中,Application_Start()中包含此行:

GlobalFilters.Filters.Add(new UserAuthenticatedAction(excludeActions, allowedRoles));

这意味着只要调用ActionMethod就会执行该属性。基本上它会检查是否允许用户访问特定网址,如果不允许该用户,则filterContext设置为将其重定向回登录页面。

我还检查当前网址是否已经是登录页面;如果是这样的话,那就不用费心去做安检了。

我想根据您的要求,有更多奇特的方法可以做到这一点,但上述方法可以满足我们的需求。

答案 1 :(得分:0)

您可以使用AJAX请求来调用EditPage操作。如果授予权限,则可以返回回调以重定向到完整的编辑页面(对于EditPageView这样的操作)。否则,可能会返回错误消息的回调。

答案 2 :(得分:0)

您始终可以重定向到错误页面并显示相应的消息。

if (!request.IsValid(Item_Edit))
{
     //skip the rest and return error
     Response.StatusCode = (int)HttpStatusCode.Forbidden;
     ViewBag.errorMessage = "Sorry you do not have access to this page";
     return View("Error")
     // Need Help Here!!!
}

在您的错误页面(共享视图文件夹中应该有一个)中,您可以添加以下行

@ViewBag.errorMessage

修改

如果您不想重定向到错误页面并停留在第x页,则可以执行以下操作

if (!request.IsValid(Item_Edit))
{
     //skip the rest and return error
     Response.StatusCode = (int)HttpStatusCode.Forbidden;
     ModelState.AddModelError("", "Sorry you do not have access to this page");
     ModelForPageX modelX = new ModelForPageX();
     // do any other setup you need to in order to render page X
     return View("X",modelX)

}

这假设您在第X页的视图中有@Html.ValidationSummary 如果没有添加以下行

@Html.ValidationSummary(true, "Unable to process the requested action:")