是否有可能制作一个过滤器,在(大部分)处理完控制器操作后,检查某个测试条件并透明地路由到用户的不同视图(即URL没有变化)? / p>
这是我对某些伪代码的最佳猜测:
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
// If some condition is true
// Change the resulting view resolution to XYZ
base.OnResultExecuting(filterContext);
}
答案 0 :(得分:7)
filterContext.Result = new ViewResult
{
ViewName = "~/Views/SomeController/SomeView.cshtml"
};
这会使行动的执行短路。
答案 1 :(得分:1)
您也可以从动作中返回视图
public ActionResult Index()
{
return View(@"~/Views/SomeView.aspx");
}
答案 2 :(得分:0)
我已将ASP.NET MVC操作过滤器的AuthorizeAttribute
扩展为DCIMAuthorize,其中我执行了一些安全检查,如果用户未经过身份验证或授权,则操作过滤器将使用户访问被拒绝的页面。我的实现如下:
public class DCIMAuthorize : AuthorizeAttribute
{
public string BusinessComponent { get; set; }
public string Action { get; set; }
public bool ResturnJsonResponse { get; set; }
public bool Authorize { get; set; }
public DCIMAuthorize()
{
ResturnJsonResponse = true;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
try
{
//to check whether user is authenticated
if (!httpContext.User.Identity.IsAuthenticated)
return false;
//to check site level access
if (HttpContext.Current.Session["UserSites"] != null)
{
var allSites = (VList<VSiteList>)HttpContext.Current.Session["UserSites"];
if (allSites.Count <= 0)
return false;
}
else
return false;
// use Authorize for authorization
Authorize = false;
string[] roles = null;
//get roles for currently login user
if (HttpContext.Current.Session["Roles"] != null)
{
roles = (string[])HttpContext.Current.Session["Roles"];
}
if (roles != null)
{
//for multiple roles
string[] keys = new string[roles.Length];
int index = 0;
// for each role, there is separate key
foreach (string role in roles)
{
keys[index] = role + "-" + BusinessComponent + "-" + Action;
index++;
}
//access Authorization Details and compare with keys
if (HttpContext.Current.Application["AuthorizationDetails"] != null)
{
Hashtable authorizationDetails = (Hashtable)HttpContext.Current.Application["AuthorizationDetails"];
bool hasKey = false;
foreach (var item in keys)
{
hasKey = authorizationDetails.ContainsKey(item);
if (hasKey)
{
Authorize = hasKey;
break;
}
}
}
}
return base.AuthorizeCore(httpContext);
}
catch (Exception)
{
throw;
}
}
public override void OnAuthorization(AuthorizationContext filterContext)
{
try
{
filterContext.Controller.ViewData["ResturnJsonResponse"] = ResturnJsonResponse;
base.OnAuthorization(filterContext);
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
// auth failed, redirect to login page
filterContext.Result = new HttpUnauthorizedResult();
return;
}
if (!Authorize)
{
//Authorization failed, redirect to Access Denied Page
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary{{ "controller", "Base" },
{ "action", "AccessDenied" }
//{ "returnUrl", filterContext.HttpContext.Request.RawUrl }
});
}
}
catch (Exception)
{
throw;
}
}
}
答案 3 :(得分:0)
这就是我最终做的事情,并且包含在一个可重用的属性中,最棒的是它在根据您的要求重定向(或应用您想要的任何结果)时保留原始URL:
public class AuthoriseSiteAccessAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
// Perform your condition, or straight result assignment here.
// For me I had to test the existance of a cookie.
if (yourConditionHere)
filterContext.Result = new SiteAccessDeniedResult();
}
}
public class SiteAccessDeniedResult : ViewResult
{
public SiteAccessDeniedResult()
{
ViewName = "~/Views/SiteAccess/Login.cshtml";
}
}
然后只需将属性[SiteAccessAuthorise]
添加到您希望应用授权访问权限的控制器(在我的情况下)或将其添加到BaseController。确保您重定向到底层控制器的操作虽然没有属性,但您将陷入无限循环!