ASP.Net MVC控制器从局部视图重定向到不同控制器的完整视图

9

好的。我有一个问题,需要在控制器操作中进行一些授权检查。

有授权角色,但可能存在某人具有TypeOnePayment但没有TypeTwo的情况。

[Authorize(Roles = "TypeOnePayment;TypeTwoPayment")]
public ActionResult EnterRevenue(PaymentType payment)
{
    payment = "TypeOne"; // This exists for show only.
    var permission = string.Concat(payment,"Permission");
    if (!SecurityUtility.HasPermission(permission))
    {
        return View("Unauthorized", "Error");
    }
    return this.PartialView("_EnterRevenue");
}

但由于这只返回了部分视图,因此“错误”屏幕仅出现在页面的部分视图中。有没有办法重定向到全新的页面?

编辑:EnterRevenue是通过ajax调用检索的。因此,只返回html并将其放置在调用它的视图中。


你在哪里使用这个Partial View?在Ajax还是Html.Action? - Marian Ban
它是通过ajax调用检索的,当调用成功时,新的html将被插入到html中。 - ELepolt
你应该阅读这篇文章:https://dev59.com/AnVC5IYBdhLWcg3wvT1a - Marian Ban
3个回答

6
你可以重定向到其他操作:
public ActionResult EnterRevenue
{
    if (!SecurityUtility.HasPermission(permission))
    {
        return View("Unauthorized", "Error");
    }
    return RedirectToAction("NotAuthorized","Error");
}

假设我们有一个名为ErrorController的控制器,其中包含动作NotAuthorized,该动作返回正常视图,显示您无权查看此页面。
如果您需要在每个操作上进行此检查,则需要实现自定义操作筛选器属性,在其中必须检查是否为正常请求重定向,否则将状态返回为JSON并从客户端重定向。请参见asp.net mvc check if user is authorized before accessing page 以下是一段代码:
public class AuthorizationAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            string actionName = filterContext.ActionDescriptor.ActionName;
            string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;


            if (filterContext != null)
            {
                HttpSessionStateBase objHttpSessionStateBase = filterContext.HttpContext.Session;
                var userSession = objHttpSessionStateBase["userId"];
                if (((userSession == null) && (!objHttpSessionStateBase.IsNewSession)) || (objHttpSessionStateBase.IsNewSession))
                {
                    objHttpSessionStateBase.RemoveAll();
                    objHttpSessionStateBase.Clear();
                    objHttpSessionStateBase.Abandon();
                    if (filterContext.HttpContext.Request.IsAjaxRequest())
                    {
                        filterContext.HttpContext.Response.StatusCode = 403;
                        filterContext.Result = new JsonResult { Data = "LogOut" };
                    }
                    else
                    {
                        filterContext.Result = new RedirectResult("~/Home/Index");
                    }

                }


                else
                {

                    if (!CheckAccessRight(actionName, controllerName))
                    {
                        string redirectUrl = string.Format("?returnUrl={0}", filterContext.HttpContext.Request.Url.PathAndQuery);

                        filterContext.HttpContext.Response.Redirect(FormsAuthentication.LoginUrl + redirectUrl, true);
                    }
                    else
                    {
                        base.OnActionExecuting(filterContext);
                    }
                }


            }

        }
 }

然后像这样将其用于操作:

[Authorization]
public ActionResult EnterRevenue
{
    return this.PartialView("_EnterRevenue");
}

我可能表达不太好。但是EnterRevenue是部分视图。因此,无论返回什么,它都只会显示在调用它的主视图上的部分视图空间中。 - ELepolt
你是如何调用EventRevenue操作的?能展示一下那段代码吗? - Ehsan Sajjad
我编辑了我的帖子,但是EnterRevenue是通过ajax调用检索的。因此,只返回HTML,并将其放置在调用它的视图中。 - ELepolt
可能有一些写得不太好的需求,但我们已经在这些页面上设置了授权。但基本上我们有许多不同的付款类型,因此需要对每种类型进行单独的检查。我会相应地更新代码。 - ELepolt
是的,您应该清楚地说明并添加相关代码,以便您的帖子不会被误解。 - Ehsan Sajjad
让我们在聊天中继续这个讨论 - ELepolt

1

或者使用标准的重定向调用。这应该在任何地方都有效(只是不要在 using 语句内部执行,否则会在后台抛出异常):

Response.Redirect("/Account/Login?reason=NotAuthorised", true);                         

0

我认为您需要的可以归纳为根据返回值使ajax呼叫采取不同行动的方法。我发现最好的做法可以总结如下:

  • 当您检测到没有权限时,请将模型状态错误添加到您的模型中。
  • 覆盖 OnActionExecuted 方法(希望所有控制器都继承自一个基类控制器,这样只需在一个地方实现即可,如果没有的话,现在实现也是个好主意)。在覆盖方法中,检查请求是否为 ajax 并且模型状态无效(如果需要,您可以检查操作方法中添加的特定错误),将请求状态更改为 4xx 状态。
  • 在ajax呼叫的 OnFailure 中,您可以使用 JavaScript 代码重定向到错误页面。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接