46

Can anybody please tell me why should I use the NonAction attribute? I mean say I have a form with several submit values: Update, Delete or Insert. Since all the submit buttons have the same form in common I'm switching the submit value inside the controller and act accordingly.

Like this:

public ActionResult asd(string submitButton){
     switch(submitButton){
         case "Insert":
             return Insert();
         // bla bla bla
     }
}

[NonAction]
public ActionResult Insert(){
    // some code inside here
    return View();
}

Once again, why should I use NonAction instead of something like this:

public void Insert(){
    // some code inside here
}
Amal K
  • 4,359
  • 2
  • 22
  • 44
Shaokan
  • 7,438
  • 15
  • 56
  • 80
  • 9
    Why make Insert public if you aren't planning on invoking it from anywhere but the asd method? – Gromer Dec 21 '11 at 20:56
  • 2
    Most of the answers are correct, but none of those is mentioning the reason behind the existence of the `ChildActionOnly/NonAction` attributes, i.e. their purpose, which was a means to have a "mini MVC" cycle within the main request's MVC cycle. Example would be a view that needs to render/embed a bit more complex partial view. So, rather than calling a `` directly, one can call a `NonAction/ChildActionOnly` decorated controller action method using `Html.RenderAction()`, to perform that "mini MVC" cycle which returns the html markup of a rendered partial view. – Mladen B. Aug 01 '19 at 08:12
  • 1
    Seems to me that such methods should be in another class and not a controller – Mark Schultheiss Oct 05 '19 at 14:08

9 Answers9

60

You can omit the NonAction attribute but then the method is still invokable as action method.

From the MSDN site (ref):

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.

Taudris
  • 1,413
  • 1
  • 15
  • 23
ReFocus
  • 1,511
  • 1
  • 18
  • 24
  • 4
    Ah alright, if you create a public void inside a controller class then when you type the url the page returns blank. Therefore, as you (MSDN actually :D) stated all public methods are treated as actionresults. So you should use NonActionAttribute whenever you don't want your method to be displayed unless you call it :) Thanks! – Shaokan Jun 17 '11 at 12:25
  • Exactly. In pre-releases of the MVC framework it was the other way around. You had to explicitly define methods as actionmethod using the `ActionMethod` attribute. From the RTM release all methods are treated as Action Method unless you use the `NonAction` attribute. – ReFocus Jun 17 '11 at 12:39
16

It is worth noting that the need to use [NonAction] applies only to public methods. Protected and private methods are not treated as actions. Since your Update/Delete/Insert methods are helpers for asd(), a private method would be more appropriate for your scenario:

public ActionResult asd(string submitButton){
    switch(submitButton){
        case "Insert":
            return Insert();
        // bla bla bla
    }
}

ActionResult Insert(){
    // some code inside here
}
Taudris
  • 1,413
  • 1
  • 15
  • 23
8

Reading Haack's Article

Any public method in a controller class is callable via URL.

Sometimes you may need to avoid this. For example, if you implement some interface and you may not want to call that public method you can mark as NonAction

public interface IEmployee
{
 void Save(Employee e);
 bool Validate(Employee e);
}

public class EmployeeController:Controller, IEmployee
{
  public void Save(Employee e){
  }

  [NonAction]
  public void Validate(Employee e){
  }
}
Murali Murugesan
  • 22,423
  • 17
  • 73
  • 120
7

I just used [NonAction] in our web api, to decorate a bunch of Controller Methods (endpoints) because we had a last minute decision that we will postpone the delivery of the specific endpoints.

So it is useful, if you want to avoid exposing an API endpoint, but still want to keep the implementation for later.

So I used this attribute and it saved me a lot of time.

I will just remove it in the next release and this will simply be there!

cnom
  • 3,071
  • 4
  • 30
  • 60
  • 2
    Just wondering what benefit this has over commenting out the method? – David Klempfner Aug 21 '18 at 08:01
  • 3
    Commented out code is not a good practice generally, but a more situation is this: Imagine you did all the implementation and some unit tests for this method. This way you dont have to comment all these out! – cnom Nov 30 '18 at 13:06
  • commented code is not testable, Can break inner blocks – Dorathoto Jan 27 '22 at 17:26
5

If you don't use the [NonAction] attribute then someone can call your action directly instead of having to go through the 'asd' function

devprog
  • 285
  • 1
  • 2
  • 10
2

NonAction attribute makes an action non accessible from the navigation bar. For example if you have an action which deletes items in database, you have to add the NonAction attribute to make it not accessible by users.

kayess
  • 3,384
  • 9
  • 28
  • 45
Bilel Chaouadi
  • 37
  • 1
  • 1
  • 6
0

Firstly, think of an ActionResult simply as a particular type of construct that is returned by MVC, that happens to provide a particular convenience in terms of the way that ActionResult can be internally handled within the MVC framework. So the fact that something is an ActionResult doesn't necessarily mean "this should be publicly available". In fact, any public method in an MVC controller will be treated as an action method, whether or not it returns an ActionResult.

So, simply having a return type that isn't an ActionResult will not necessarily prevent that method from being exposed as a publicly available action that can be called via a URL.

There may be many reasons you don't want to expose a method as an action that can be invoked via a url, and in the case that you want to 'protect' against this, that's when you use the [NonAction'] attribute.

Chris Halcrow
  • 28,994
  • 18
  • 176
  • 206
0

This is indicate that a controller method is not an action method.Example: [NonAction] public void IndexTest() { // Do some thing } this is very useful attribute when visibility of controller 's method cannot be changed to private.

Ajeet Malviya
  • 784
  • 1
  • 5
  • 9
-1

If you did not want to invoke some action methods then you have to mark it with a attribute [NonAction] or by making it private

public ActionResult Index(){
    return View();
}

[NonAction]
public ActionResult Countries(List<string>countries){
    return View(countries);
}

you can copy the code and paste it and see the result.thanks

Arash GM
  • 10,316
  • 6
  • 58
  • 76