This may be pie in the sky but I'm wondering if the following could be accomplished with a custom controller attribute.
For a majority of my controllers, I will be passing in an URL parameter called "r" to each action within the controller. "r" is tied to a race id in the races 开发者_运维问答table in my database.
What I would like to happen is that any time a controller action is invoked, it'll automatically check for the existence of "r", query the database to make sure "r" belongs to the logged in user and set a viewbag variable called ViewBag.RaceId equal to "r".
If any of those conditions aren't met, it'll redirect them back to the login page.
I'm trying to make my code as DRY as possible.
Any guidance would be greatly appreciated.
You could write a custom Authorize
attribute:
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isAuthorized = base.AuthorizeCore(httpContext);
if (isAuthorized)
{
var request = httpContext.Request;
// Fetch "r" from the route data or request
var r = request.RequestContext.RouteData.Values["r"]
?? request["r"];
var currentUser = httpContext.User.Identity.Name;
if (!CheckIfRBelongsToTheCurrentLoggedInUser(currentUser, r))
{
return false;
}
}
return isAuthorized;
}
}
Now all that's left is to decorate your controllers/actions with this custom attribute:
[MyAuthorize]
public ActionResult Foo()
{
//...
}
And if you wanted to put something into the ViewBag you could temporarily store it in the httpContext.Items
inside the AuthorizeCore
method in case of success and then override the OnAuthorization
method as well and check for the presence of this item in the context. If it is present you could store it in the filterContext.Controller.ViewBag
.
精彩评论