I have the following base controller
public class BaseController : Controller
{
protected override void Execute(RequestContext requestContext)
{
base.Execute(requestContext);
}
}
Implementation is
public class HomeController : BaseController { }
we upgraded from mvc3 to mvc5 , in mvc5 this method is not getting called what needs to be done here ?
It's not entirely clear what your after but here's a few questions. Are your normal controllers inheriting your BaseController?
public class MyController : BaseController
I don't see what this line is meant to do....
var global = requestContext.HttpContext.Request.QueryString["global"] == null ? true : false;
You set the value then don't do anything with it. Are you meaning to store this value in the base controller so that you can access it from all your other controllers?
And surely if global is missing from the querystring then it should be false and not true.
public class BaseController : Controller
{
public bool isGlobal { get; private set; }
protected override void Execute(RequestContext requestContext)
{
this.isGlobal = requestContext.HttpContext.Request.QueryString["global"] == null ? false : true;
base.Execute(requestContext);
}
}
The title of this question led me here, but it's not really the same problem I was experiencing (i.e. the overridden Execute method in a base controller class not being called in an MVC 4/5 web site).
If that is the problem you are having too, this is the solution I found. It appears the way in which these methods are called has changed with the introduction of Async support. Instead of overriding the Execute method you should override the OnActionExecuted method instead.
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
}
Related
I am creating a session control on my project and I need help at the moment.
Basically, my HomeController inherits from CustomController.
HomeController manages the methods and CustomController runs before methods to check session info.
public class HomeController : CustomController
{
public ActionResult Index()
{
}
}
public class CustomController : Controller
{
public OnActionExecuting()
{
// Check session
}
}
My problem is, I do not want to check Session before HomeController/Index method. Is this possible?
You could do it with a custom attribute class as follows:
/// <summary>
/// Indicates whether session checking is enabled for an MVC action or controller.
/// </summary>
public class CheckSessionAttribute : Attribute
{
public CheckSessionAttribute(bool enabled)
{
this.Enabled = enabled;
}
public bool Enabled { get; }
}
Then annotate the action method you want to exclude session checking with [CheckSession(false)].
Lastly, include the following in the OnActionExecuting method of the base class:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Check if the CheckSession attribute is present and skip the session
// check if [CheckSession(false)] was explicitly provided.
bool checkSession = filterContext.ActionDescriptor.GetCustomAttributes(typeof(CheckSession), true)
.OfType<CheckSession>()
.Select(attr => attr.Enabled)
.DefaultIfEmpty(true)
.First();
if (checkSession)
{
// Check session
}
}
This checks for the presence of the [CheckSession(false)] attribute and disables the session check in that case. In this way, you can configure the methods that should not check the session info simply by annotating them with the new attribute. This also makes it immediately clear that the session is not checked for that specific action.
I am struggeling with this peace of code:
public class MultiDatabaseAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
}
}
I want to execute the OnActionExecuting on certain ActionResults in my API. This is a method in my API:
[MultiDatabase]
public Website Get(int id)
{
return _websites.Get(id);
}
It does not work. Whatever I try, the method attribute is not called. According to the website http://www.strathweb.com/2015/06/action-filters-service-filters-type-filters-asp-net-5-mvc-6/ this should work.
According to this question I had to add the attribute to the Global.asax. Did not help too.
Who can help me?
Thanks
You are inheriting your attribute from the wrong base class. MVC and WebAPI have different objects (at least until ASP.Net Core has since merged them into one). Make sure you have the correct import in your attribute:
using System.Web.Http.Filters;
Or use the full namespace:
public class MultiDatabaseAttribute : System.Web.Http.Filters.ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
base.OnActionExecuting(actionContext);
}
}
I'm building the below filter:
public class TestflowFilter : FilterAttribute, IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{
var profileId = int.Parse(ClaimsPrincipal.Current.GetClaimValue("UserId"));
var appId = int.Parse(filterContext.RouteData.Values["id"].ToString());
if (profileId != 0 && appId != 0)
{
if (CheckIfValid(profileId, appId))
{
// redirect
filterContext.Result = // url to go to
}
}
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
}
}
I actually only need OnActionExecuted, but since IActionFilter is an interface I have to implement them both. Is it ok to leave OnActionExecuting blank if I don't need anything to happen, or do I need to call a base version that MVC always runs?
Also in the OnActionExecuted method if the CheckIfValid is true I redirect the user, but if not I don't do anything. Is that ok or do I need to set some property on the filterContext instead.
I actually only need OnActionExecuted, but since IActionFilter is an interface I have to implement them both. Is it ok to leave OnActionExecuting blank if I don't need anything to happen, or do I need to call a base version that MVC always runs?
Leaving the method body empty is perfectly acceptable in this case. Looks good!
Also In the OnActionExecuted method if the CheckIfValid is true I redirect the user, but if not I don't do anything, is that ok or do I need to set some property on the filterContext instead.
Your filter is fine. MVC does offer a different abstract base class called ActionFilterAttribute, which implements these interfaces for you to override as needed. There's a nice overview that you can read about here. If you derive from that class, your filter attribute code could be simplified a little bit:
public class TestflowFilter : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var profileId = int.Parse(ClaimsPrincipal.Current.GetClaimValue("UserId"));
var appId = int.Parse(filterContext.RouteData.Values["id"].ToString());
if (profileId != 0 && appId != 0)
{
if (CheckIfValid(profileId, appId))
{
// redirect
filterContext.Result = // url to go to
}
}
}
}
I want to call controller method in Global.asax. Code is given below.
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
//here we can subscribe user to a role via Roles.AddUserToRole()
}
}
This event is in global.asax. I want to call controller method which return user permissions from database. How this is possible to call controller method here after that I will save user permissions in session and my controller constructor? Code is given below.
public class AccountController : Controller
{
private readonly ISecurityService securityService;
public AccountController(ISecurityService securityService)
{
this.securityService = securityService;
}
}
Please guide me.
You could handle this using a custom AuthorizeAttribute. This allows you to place an attribute on the top of any controllers / methods which you require authentication to be successful in order to call. This lets you override AuthorizeCore which you can then use to do any custom authorization you want to perform. You can also save any other information to session from this method.
For example:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
// do your own athorization stuff here
}
}
Then you can decorate you controllers that require the use of this authorization either with your attribute:
[CustomAuthorize]
public class AccountController : Controller
{
}
Or using a base controller:
[CustomAuthorize]
public class BaseAuthController : Controller
{
}
public class AccountController : BaseAuthController
{
}
i Resolve this issue by my self i call service method in global.asax by resolving dependency issue below is the solution of the above problem.
protected void Application_PostAuthenticateRequest(Object sender, EventArgs e)
{
if (User.Identity.IsAuthenticated)
{
IUnityContainer container = GetUnityContainer();
ISecurityService securityService = container.Resolve<SecurityService>();
var list = securityService.GetUserRolesandPermissions("1");
}
}
Thank you every one.
I'm having some problem with my custom AuthorizeAttribute
public class ExplicitAuthorizeAttribute : AuthorizeAttribute
{
private readonly MembershipUserRole[] _acceptedRoles;
public ExplicitAuthorizeAttribute()
{
}
public ExplicitAuthorizeAttribute(params MembershipUserRole[] acceptedRoles)
{
_acceptedRoles = acceptedRoles;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
//Validation ...
}
}
I use it like this:
[ExplicitAuthorize[(MembershipUserRole.Admin, MembershipUserRole.SuperAdmin)]
It works perfectly for HttpGet and HttpPost to validate my controllers and methods.
But when I use it in a ApiController and make ajax calls, AuthorizeCore isn't running and I got a security breach. :/
My enum looks like this
[Flags]
public enum MembershipUserRole
{
Admin= 1,
SuperAdmin = 2
}
Does anyone know why my AuthorizeCore isn't validating in this context?
By the way If I use
[Authorized(Roles ="Admin, SuperAdmin")]
It's validates perfectly, but I'd like to have Stronly Typed Roles,that's why I'm using enums.
You have derived from the wrong class: System.Web.Mvc.AuthorizeAttribute whereas for a Web API controller you should derive from System.Web.Http.AuthorizeAttribute.
Don't forget that ASP.NET MVC and ASP.NET Web API are 2 completely different frameworks and even if they share some common principles and names, the corresponding classes are located in 2 completely different namespaces.
So what you have done is decorate an ASP.NET Web API action with an AuthorizeAttribute that it doesn't know anything about.
If you want to make authorization in ASP.NET Web API make sure you have derived from the correct attribute:
public class ExplicitAuthorizeAttribute : System.Web.Http.AuthorizeAttribute
{
private readonly MembershipUserRole[] _acceptedRoles;
public ExplicitAuthorizeAttribute()
{
}
public ExplicitAuthorizeAttribute(params MembershipUserRole[] acceptedRoles)
{
_acceptedRoles = acceptedRoles;
}
protected override bool IsAuthorized(HttpActionContext actionContext)
{
//Validation ...
}
}