1

我正在通过自定义操作过滤器为我的 MVC 应用程序实现授权机制。

我为授权提供了以下自定义操作过滤器:

[AttributeUsageAttribute(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class AuthorizationFilterAttribute : ActionFilterAttribute
{
    public AuthorizationEntity Entity { get; set; }
    public AuthorizationPermission Permission { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        AuthorizationResult result = null;
        // Base actions (Authentication first)
        base.OnActionExecuting(filterContext);
        BaseController controller = filterContext.Controller as BaseController;
        if (controller != null)
        {   // Base actions (Authorizatioın next)
            User usr = controller.currentUser;
            AuthorizationResult ar = AuthorizationManager.GetAuthorizationResult(this.Entity, this.Permission, usr.UserId, usr.RoleId);
            if (!ar.IsAuthorized)
            {
                throw new UnauthorizedAccessException(ar.Description);
            }
            // Authorized, continue
            return;
        }
    }
}

在我的基本控制器类中,我正在处理UnauthorizedAccessException类型的异常并通过以下代码将它们重定向到警告页面

protected override void OnException(ExceptionContext filterContext)
{
    if (filterContext.Exception is UnauthorizedAccessException)
    {
        if (!filterContext.HttpContext.Request.IsAjaxRequest())
        {
            Exception ex = filterContext.Exception;

            filterContext.ExceptionHandled = true;
            filterContext.Result = new ViewResult()
            {
                ViewName = "UnauthorizedAccess"
            };
        }
        else
        {
            throw filterContext.Exception;
        }
    }
}

此机制适用于返回ActionResult的操作。但我也有一些 AJAX 调用,我不想重定向到警告页面,但会显示警告弹出窗口。这就是为什么我检查了请求是否是 Ajax 调用不是。

我正在使用以下代码进行 Ajax 调用:

$.ajax({
    type: "POST",
    url: "AjaxPostMethodName",
    dataType: "json",
    data:
        {
            postval: [some value here]
        },
    success: function (msg) {
        // Do some good actions here
    },
    error: function (x, t, m, b) {
        // Display error
        alert(m);
    }
})

转到控制器上的以下方法

public JsonResult AjaxPostMethodName(string postval)
{
    try
    {
       // Some cool stuff here
        return Json(null);
    }
    catch (Exception ex)
    {
        Response.StatusCode = UNAUTHORIZED_ACCESS_HTTP_STATUS_CODE;
        return Json(ex.Message);
    }
}

但是当我没有通过授权检查时,它直接显示“内部服务器错误”消息,而不是落入AjaxPostMethodName方法的 catch 块并显示正确的消息。

如何使这样的代码显示filterContext.Exception而不是静态的“内部服务器错误”消息?

问候。

4

3 回答 3

1

我终于在另一个 Stack Overflow 帖子中找到了我的解决方案的答案(我可以将自定义错误从 JsonResult 返回到 jQuery ajax 错误方法吗?)。我应该使用JsonExceptionFilterAttribute如下:

public class JsonExceptionFilterAttribute : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
        {
            filterContext.HttpContext.Response.StatusCode = 500;
            filterContext.ExceptionHandled = true;

            string msg = filterContext.Exception.Message;
            if (filterContext.Exception.GetType() == Type.GetType("System.UnauthorizedAccessException"))
            {
                msg = "Unauthorized access";
            }

            filterContext.Result = new JsonResult
            {
                Data = new
                {
                    errorMessage = msg
                },
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        }
    }
}
于 2015-01-08T18:01:04.777 回答
0

OnException当您的代码中存在未处理的异常时,您的方法将被调用。在您的 ajax 方法中AjaxPostMethodName,您已将代码放入try catchblcok 中。因此,此方法中的任何异常都不会进入您的OnException方法。

于 2015-01-08T11:03:43.357 回答
0

我刚刚检查了 Response.StatusCode 行为,对我来说它有效。

Index.cshtml

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>


<script type="text/javascript">
    $(document).ready(function () {
        alert('doc ready');
        $.ajax({
            type: "POST",
            url: '@Url.Action("AjaxPostMethodName")',                
            dataType: "json",
            data:
                {
                    test: '10'
                },
            success: function (msg) {
                // Do some good actions here
                alert('success');
                alert(msg);
            },
            error: function (x, t, m, b) {
                // Display error
                alert('error');
            }
        });
    });
</script>

家庭控制器.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public JsonResult AjaxPostMethodName(string postval)
        {
            Response.StatusCode = 401;
            return Json("test");
        }

    }
}

当我将 Response.StatusCode 设置为 200 时,它调用成功,当 401 时调用错误。

请验证您的代码的其他部分是否不会以某种方式干扰它。

您也可以尝试以下解决方法 - 如果 AjaxPostMethodName 抛出异常返回 JSON 具有标志 isValid 和消息 errorMessage,因此在您的 ajax 成功方法中,您可以检查 isValid 是否正常并处理错误。

于 2015-01-08T11:26:42.207 回答