更多控制ASP.Net MVC的授权;保持AJAX请求AJAXy

时间:2009-06-03 06:25:12

标签: asp.net-mvc ajax authorize

我在Authorize后面有一些操作方法,如:

[AcceptVerbs(HttpVerbs.Post), Authorize]
public ActionResult Create(int siteId, Comment comment) {

我遇到的问题是我通过AJAX向评论/创建

发送请求
X-Requested-With=XMLHttpRequest

有助于将请求标识为AJAX。当用户未登录并点击授权墙时,它将被重定向到

/Account/LogOn?ReturnUrl=Comment%2fCreate

打破了AJAX工作流程。我需要被重定向到

/Account/LogOn?X-Requested-With=XMLHttpRequest

任何想法如何实现?有什么方法可以更好地控制在请求授权时发生的事情?

4 个答案:

答案 0 :(得分:5)

感谢刘易斯的评论,我能够达到这个解决方案(这远非完美,发表了我自己的评论,如果你有修复可以随意编辑和删除这个短语),但它的工作原理:

public class AjaxAuthorizeAttribute : AuthorizeAttribute {
    override public void OnAuthorization(AuthorizationContext filterContext) {
        base.OnAuthorization(filterContext);
        // Only do something if we are about to give a HttpUnauthorizedResult and we are in AJAX mode.
        if (filterContext.Result is HttpUnauthorizedResult && filterContext.HttpContext.Request.IsAjaxRequest()) {
            // TODO: fix the URL building:
            // 1- Use some class to build URLs just in case LoginUrl actually has some query already.
            // 2- When leaving Result as a HttpUnauthorizedResult, ASP.Net actually does some nice automatic stuff, like adding a ReturnURL, when hardcodding the URL here, that is lost.
            String url = System.Web.Security.FormsAuthentication.LoginUrl + "?X-Requested-With=XMLHttpRequest";
            filterContext.Result = new RedirectResult(url);
        }
    }
}

答案 1 :(得分:3)

最近我遇到了完全相同的问题并使用了J.PabloFernández发布的代码 修改帐户的返回网址。这是:

public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    override public void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
        // Only do something if we are about to give a HttpUnauthorizedResult and we are in AJAX mode. 
        if (filterContext.Result is HttpUnauthorizedResult && filterContext.HttpContext.Request.IsAjaxRequest())
        {
            // TODO: fix the URL building: 
            // 1- Use some class to build URLs just in case LoginUrl actually has some query already. 
            HttpRequestBase request = filterContext.HttpContext.Request;
            string returnUrl = request.Path;
            bool queryStringPresent = request.QueryString.Count > 0;
            if (queryStringPresent || request.Form.Count > 0)
                returnUrl += '?' + request.QueryString.ToString();
            if (queryStringPresent)
                returnUrl += '&';
            returnUrl += request.Form;
            String url = System.Web.Security.FormsAuthentication.LoginUrl +
                         "?X-Requested-With=XMLHttpRequest&ReturnUrl=" +
                         HttpUtility.UrlEncode(returnUrl);
            filterContext.Result = new RedirectResult(url);
        }
    }
}

答案 2 :(得分:1)

我没有使用authorize属性,而是做了类似以下的事情。

public ActionResult SomeCall(string someData)
{
    if (Request.IsAjaxRequest() == false)
    {
        // TODO: do the intended thing.
    }
    else
    {
        // This should only work with AJAX requests, so redirect
        // the user to an appropriate location.
        return RedirectToAction("Action", "Controller", new { id = ?? });
    }
}

答案 3 :(得分:0)

我认为处理这个问题的正确方法是在你的Javascript中进行AJAX调用。

如果用户需要获得授权(或根据您的代码所暗示进行身份验证)而不是,则应通知他们,并且可能不允许他们首先尝试发表评论。

但是,如果这不符合您的需求。 您可以尝试编写自己的授权操作过滤器,也可以继承MVC框架附带的过滤器,但重定向您希望的方式。这很简单。