ASP.NET MVC: Using NonActionAttribute to restrict access to public methods of controller
Public non-action methods in ASP.NET MVC controllers are source of problems because they can be called by user when not handled carefully. Same time you may need public methods on controllers for some other reasons (some UI framework, testability problems, things you cannot change etc). In this posting I will show you how to handle controller methods properly.
Calling controller methods
Public methods of controller are called controller actions and these actions are mapped to URL-s using routes. Take a look at the following code.
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
You can see here two controller methods. One of them is Index() and it is expected to be called by browser. The other one – DoInternalStuff() – is intended only for internal use.
public void DoInternalStuff()
{
Response.Write("We are doing internal stuff here!");
Response.End();
}
Although these examples are primitive ones they let us illustrate the situation very well.
Calling non-action method
As you can guess then first method returns out-of-box default page that comes with ASP.NET MVC web application project. But what happens when we try to call this other method? The result is here.
We can call this method directly through browser and if it contains arguments we may be able to inject them too under certain circumstances. This is something we don’t want to happen.
Restricting access to non-action methods
To restrict access to non-action method you must use NonActionAttribute to notify MVC framework that given controller method is not action. The code is here:
[NonAction]
public void DoInternalStuff()
{
Response.Write("We are doing internal stuff here!");
Response.End();
}
Now when we try to run DoInternalStuff() over URL we get the error 404 as response to request.
Conclusion
There are situations where non-action controller methods are used and there may even exist situations where visibility of these methods cannot be changed. To avoid users to invoke those methods directly – this can be considered as security hole – we have to say MVC framework using NonActionAttribute that these methods are not controller actions.
I’m curious what the use case is for having non action result public methods?
In my opinion, I would consider it bad design having a public method on a controller that is not an ActionResult. Any such method I think should probably be in the model somewhere.
Thanks for feedback Justin and Paul!
Paul, you are absolutely correct that this is bad design. But in same time this kind of situation may be caused by requirements some testing framework by example (have seen many “testing” frameworks built in companies). It is also possible that somebody hasmade decision like this and you are not at position to change it.
If it is possible then avoid these kind of methods or change their visibility so they are not shown by controller.
Its just Beautiful.
Thanks a lot