The code below was copied from this post. I see in other posts the same thing, such as in the answer for this this post.
Why is the line base.OnActionExecuting(filterContext); included inside the overall OnActionExecuting methods?
What purpose does it fulfill?
public class HomeController : Controller
{
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
// do some irrelevant stuff
base.OnActionExecuting(filterContext);
}
public ActionResult Index()
{
return View();
}
}
Short answer:
currently, the line base.OnActionExecuting(filterContext) does not do anything (performs no work). The functional behavior will be the same with or without the line.
Longer answer:
The .NET source code for Controller.OnActionExecuting looks as follows (taken from here):
protected virtual void OnActionExecuting(ActionExecutingContext filterContext)
{
}
If you look at the OnActionExecuting method, you'll see this method is completely empty. This is the code/method that base.OnActionExecuting(filterContext) is calling. You don't have to call base.OnActionExecuting(filterContext) as it currently does nothing however I would recommend doing so. The reason behind this is that if .NET framework is updated such that the Controller.OnActionExecuting method actually has needed code it in it, then the needed code will not be called without including the line in question. This could lead to some scenarios that can be pretty difficult and time-consuming to debug. It's also certainly possible for new framework code to be introduced that does break your code when you call base.OnActionExecuting however this scenario is generally easier to spot and fix than the other. Of course in the end, it's all going to come down to what code the framework introduces and what it breaks for how easy it is to identify and resolve.
As a side-note, .NET framework is in maintenance mode now so I highly doubt the example I mentioned above with .NET framework updating the code in Controller.OnActionExecuting will ever happen however it serves as a good best practice in other similar scenarios as well.
Related
I'm reading through the ASP.NET 5 docs and was choking on the chapter of dependency injection.
I am recommended to write my controllers like so:
public class MyController: Controller
{
private readonly MyService _myService;
public MyController(MyService myService)
{
_myService = myService;
}
public IActionResult Index()
{
// use _myService
}
}
The short and direct version is discouraged:
public class MyController : Controller
{
public IActionResult Index()
{
var myService = (MyService)HttpContext.RequestServices.GetService(typeof(MyService));
}
}
The given reason is because allegedly the recommended version...
[...] yields classes that are easier to test (see Testing) and are more loosely coupled.
The linked testing chapter doesn't shed any light on this weird statement.
I didn't look at the sources, but I assume whatever constructs the controller is using HttpContext.RequestServices.GetService itself to deliver the dependency? Clearly a test can setup a different implementation for testing, and clearly that is the whole point of a DI framework, right?
The colossus (MyService)HttpContext.RequestServices.GetService(typeof(MyService)) is bad enough, but a small helper could fix that (was a simple Get<MyService>() really so hard?).
But that this excessive clutter is recommended for basically every controller and more is disturbing.
It's all the more puzzling as there already is a Microsoft DI framework with a proper usage, MEF:
public class MyController : Controller
{
[Import]
private MyService _myService;
public IActionResult Index()
{
// use _myService
}
}
Why not at least just take that one? What's going on here?
This isn't a ASP.NET Core specific solution. This is how just about every DI framework works. The most common approach is to have all the dependencies of a controller as constructor parameters. This makes it clear what services the controller uses. There are multiple alternative solutions, but the basic idea stays the same and there are multiple pros and cons to them.
Clearly a test can setup a different implementation for testing, and clearly that is the whole point of a DI framework, right?
This line isn't clear to me. What do you think the 'whole point of a DI framework ' is? This line suggest you only use it so you can use a different implementation for testing.
But that this excessive clutter is recommended for basically every controller and more is disturbing.
Excessive clutter? What if I want to use MyService in two (or more) functions? Should I use this:
public class MyController : Controller
{
public IActionResult Index()
{
var myService = (MyService)HttpContext.RequestServices.GetService(typeof(MyService));
}
public IActionResult Index2()
{
var myService = (MyService)HttpContext.RequestServices.GetService(typeof(MyService));
}
}
Or should I opt for the solution where I set it up in the constructor? Seems like an obvious choice to me. In such a small example it may look like clutter, but add 10 lines of code to it and you'll barely notice a small constructor and some variable declarations.
You can use it while testing. It's a way to quickly grab something from the container when you need it, but it should certainly not be part of the actual code. You're simply hiding the dependency from sight.
At last you suggest property injection. This is a valid solution. But an often used argument against it is that it hides the dependency. If you define it as a parameter in the constructor you can't hide it. Besides, a lot of DI frameworks don't even have support for property or method injection because of this.
If you want to use MEF in your project you are free to do so. But it should, in my opinion, not be the default DI framework for ASP.NET. What's available right now is more than sufficient to do most tasks. If you need more functionality you can always use a different DI framework like StructureMap or AutoFac.
In the end it all comes down to what works for you. But stating this is either bad design or bad documentation is just wrong. You are of course free to prove me wrong on this. You could improve the ASP.NET documentation and/or would prove that the concept of inversion of control is wrong and suggest a better solution.
i have just started working in MVC and I have one doubt.
Instead of Nonaction method , we can create private method in controller or we can also write method in model and call that from controller.
So , what is the real purpose to use public NonAction method in MVC ?
(I restructured the answer to better address the questions in the comments)
I think, the attribute is here only for better flexibility. As a framework designer, one wants to relax coding constraints off the end user as much as possible. Requirement of not having public non-actions may sound good "in general" but may be too restrictive for some projects. Adding [NonAction] solves their problem (introduced by their bad design though) - and obviously you're not forced to use the attribute, so it's a win-win from a framework designer perspective.
Another reason may be legacy - in the earlier MVC versions only methods marked with [Action] where considered as actions. So when they relaxed the requirement (and all public methods became treated as actions) they kept [NonAction] so that developers won't get too confused.
In general, using NonAction is a bad practice - exactly for the reasons you stated. If something shouldn't be an action, it should not be public in the first place.
Problem with public non-action methods on the controller is that they make people tempted to instantiate your controller and call the method, instead of separating out the common logic:
Compare
public class MyController : IController
{
public ActionResult Foo(long orderId)
{
var order = new OrdersController().GetOrder(orderId); //GetOrder is public
...
}
}
with
public class MyController : IController
{
public ActionResult Foo(long orderId)
{
var order = _orderService.GetOrder(orderId);
...
}
}
The first approach leads to increased coupling between controllers and non-straightforward code in the actions. Code becomes difficult to follow and refactor, and cumbersome to mock/test.
Besides increased coupling, any public non-action method is a security hole - if you forget to mark it with [NonAction] (or, better, change away from public) - because it's treated as normal action and can be invoked externally. I know the original question kinda implies you surely would never forget to attach the attribute if needed, but it's also kinda important to understand what can happen if you would ;) Oh well, and as we're on this, it seems to me that "forgetting the attribute" is more theoretically probable, comparing to "forgetting to make the method private".
Sometimes people say having public non-actions is necessary for unit testing, but again, when something is not an action it most likely can be isolated in a separate class and tested separately. Moreover, even if it's not feasible for whatever reason, marking a method public for testing purposes only is a bad habit - using internal and InternalsVisibleTo is the recommended way.
This kind of situation may be caused by requirements some testing framework such as you need to do unit testing on that method then you to expose it although its a bad design but can't change these had to bear it out.
By default, the MVC framework treats all public methods of a controller class as action methods. If your controller class contains a public method and you do not want it to be an action method, you must mark that method with the NonActionAttributeattribute.
Real purpose to use public NonAction
To restrict access to non-action method to notify MVC framework that given controller method is not action.
When you try to run a method with NonAction attribute over URL you get the error 404 as response to request.
Ref: http://msdn.microsoft.com/en-us/library/dd410269%28v=vs.90%29.aspx
For Detail: http://weblogs.asp.net/gunnarpeipman/archive/2011/04/09/asp-net-mvc-using-nonactionattribute-to-restrict-access-to-public-methods-of-controller.aspx
This is beneficial when the Url are not case sensitive. So that for example if you have the request Home/About this goes to HomeController and About action, as well as hOmE/AbOUT is going to the same controller and same action method.
Like below
public class HomeController:Controller
{
....
public ViewResult About()
{
return View();
}
public ViewResult aBOut()
{
return View();
}
}
The framework can’t determine which about function to call, and throws the exception telling that the call is ambiguous.
Of course one way to fix this problem is to change the action name.
If for some reason you don’t want to change the action name, and one of these function is not an action, then you can decorate this non action method with NonAction attribute. Example:
[NonAction]
public ActionResult aBOut()
{
return View();
}
By default, the MVC framework treats all public methods of a controller class as action methods. If your controller class contains a public method and you do not want it to be an action method, you must mark that method with the NonActionAttribute attribute.
We are using controllers as binding drivers with custom ASP pipeline, each driver is responsible for rendering one section (partial view) of result page. Then we are using public methods like:
[NonAction]
publi int GetOrder()
to resolve sections order on page or other to resolve authorization for current user (e.g. if current section is editable or just read-only).
So you should not restrain yourself to think about Controller as only a way to handle requests but also as a tool to build your custom framework for rendering page. That way we keep our Controllers responsible for exactly one task and we are separating domain concerns.
ASP.NET is highly customizable. Assume you are going to change the default behavior of the framework by overriding the MVC HTTP handler. Maybe you want to customize the logging logic depending on the controller, which is used. Some controllers implement your ILoggingController interface with the method IControllerLogger GetLogger(). For this method you need to write a public non-action method.
I got ASP.NET MVC application and I'm using EF code first and Unity dependency injector.
I've implemented the DDD design and have repositories and services which interact with my POCO objects.
My problem is that I'm getting EF related problems - such as the connection was closed, the entities changed or not tracked and so on. As I've understand from researches in Google, it related to the way that I should configure Unity.
I've understood that I need to put it as per request instance, but as I see there's no built-in strategy in Unity nor in the Unity.Mvc3 package.
I've tried to write my own strategy, which solved many problems but I do stuck with the problem that sometimes I get "connection closed".
My HttpContextLifetimeManager.cs
public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable
{
public override object GetValue()
{
return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
}
public override void RemoveValue()
{
HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
}
public override void SetValue(object newValue)
{
HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = newValue;
}
public void Dispose()
{
RemoveValue();
}
}
And inside DependencyConfig.cs (MVC 4 App_Start) I'm registering it using:
container.RegisterInstance<MyDbContext>(new MyDbContext(), new HttpContextLifetimeManager<DependencyConfig>());
Can you recommend me an implementation that works/help me fix mine/forward me to an article or a tutorial that can help me solve that problem?
Thanks a lot.
App_Start method is only called once when the first request comes for the application.
Called when the first resource (such as a page) in an ASP.NET application is requested.
The Application_Start method is called only one time during the life cycle of an application.
See MSDN
Therefore you are creating the one context for all requests. Then after sometimes it may be disposed. And it's not a good practice to keep one DbContext for all the requests (memory issues etc..).
So you can try putting that code in the Application_BeginRequest .
In my MVC4 app, there are some actions that need to behave differently depending on whether you are logged in (FormsAuthentication in my case) or not.
For example, I have an AccountController that has a method "RenderAccountAndProfile". If logged out, the corresponding partial view displays a log in prompt and button. If a user is logged in, the user's profile links appear, alongside a log out button.
The approach I've taken thus far in projects is to simply have an if statement along the lines...
if (HttpContext.User.Identity.IsAuthenticated)
{
...
}
else
{
...
}
However, I've just created what I think is a reasonably elegant alternative to this approach.
I have created a new attribute called AnonymousUsersOnly, which is very simple:
public class AnonymousUsersOnlyAttribute : System.Web.Mvc.ActionMethodSelectorAttribute
{
public override bool IsValidForRequest(System.Web.Mvc.ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
{
return !controllerContext.HttpContext.User.Identity.IsAuthenticated;
}
}
My AccountController class is decorated with the Authorize attribute. This then enabled me to have the following code:
[Authorize]
public class AccountController : Controller
{
[AllowAnonymous]
[AnonymousUsersOnly]
[ActionName("RenderAccountAndProfile")]
public ActionResult RenderAccountAndProfile_Anonymous()
{
// create a "logged out" view model
return Content("**NOT LOGGED IN** - LOG IN HERE");
}
[ActionName("RenderAccountAndProfile")]
public ActionResult RenderAccountAndProfile_Authorized()
{
// create a "logged in" view model
return Content("**LOGGED IN** - LOG OUT");
}
}
I quite like this approach because my action methods conform to the Single Responsibility Principle. Each method now only deals with either a logged in situation or a logged out situation. I don't need any "if" statements directing the traffic any more.
This ought to make Unit Testing easier too, since each method is now only concerned with one outcome, not two. We can write unit tests to test each outcome separately, calling different methods.
Clearly, I can't have two methods with the same signature so that's why I have to use the ActionName attribute.
I would appreciate your critique here. Do you think this is an elegant solution or not? What are the pros and cons to this approach? And what security implications/risks could there be with this?
The problem you have here is a strategy pattern problem. And you've implemented a (non-standard) strategy pattern, with a pretty clever implementation. I worry that it is too clever. That cleverness makes what the code is doing a lot less obvious to the uninitiated.
Offhand, I'd favor not bothering. I often write controllers as very thin adapters over domain objects/services. Therefore, I'm willing to take a pragmatic approach to design perfection in the controller. In deciding between slight design problems and obvious code, always choose obvious code.
If you have thicker controllers, or some other reason to be really concerned about this problem here, you might consider a more traditional strategy pattern, perhaps aided by an abstract factory that provides different strategy implementations based on authentication state. This meets your design objectives, and will be more immediately familiar to other programmers (if they know design patterns).
All that being said, I don't think keeping your clever solution will hurt anything that much. I'd be tempted to change the name; Deny seems like a weird verb there to me. Perhaps AnonymousUsersOnly, that would be a little more communicative to future programmers.
I much better choose to (pseudocode) :
PartialView UserProfile() { ... }
PartialView Login() { ... }
and in view :
if (User.IsAuthenticated) {
#Html.Action("UserProfile")
} else {
#Html.Action("Login")
}
which can also be a DisplayTemplate, helper, or whatever you like so you just end up using
#Html.DisplayFor(m=> User)
I asked a question earlier today about ActionFilters in ASP.Net MVC. It turned out my problem was really that my ActionFilter is not even running. Among other things I read this article, and I can't find anything he does that I don't.
This is my code:
// The ActionFilter itself
public class TestingIfItWorksAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.Controller.TempData["filter"] = "it worked!";
base.OnActionExecuting(filterContext);
}
}
// The Controller Action with the filter applied
[TestingIfItWorks]
public ActionResult Test()
{
var didit = TempData["filter"];
return View();
}
A breakpoint in the filter method is never hit when I debug, and TempData["filter"] holds a null value when the view is rendered.
Why is this not working?
In case it's helpful to anyone using MVC 4/5:
ActionFilters don't run if you get the namespace of your ActionFilterAttribute or IActionFilter wrong: https://stackoverflow.com/a/13710468/188926
Use System.Web.Http.Filters for Web API, System.Web.Mvc for standard MVC actions.
As in the question, the filter attribute will simply be ignored (no error) if you get it wrong, which makes it difficult to diagnose.
Based on your comments to another answer
When testing via unit tests, the filter is not invoked. If you want to invoke the filter then you'll need mimic the ControllerActionInvoker. It's probably better, to test the filter itself in isolation, then use reflection to ensure that the filter is applied to your action with the correct attributes. I prefer this mechanism over testing the filter and action in combination.
Original
Surely you need an override on your method otherwise you aren't actually replacing the method on the base class. I would have expected the compiler to complain that you needed either a new or override on it. If you don't include the override keyword, it will behave as if you used new. Since the framework invokes it as an ActionFilterAttribute, this means that your method will never get called.
Quoting from MSDN:
If the method in the derived class is
not preceded by new or override
keywords, the compiler will issue a
warning and the method will behave as
if the new keyword were present.
In addition to what tvanofosson said, your action method isn't actually rendering anything to the view. Does your view have a <%=TempData["Filter"].ToString()%> statement or something similar?