I am new to MVC. I was going through the asp.net site and found this link where it stated that public methods (actions) cannot be overloaded in controller classes. However in the site it stated that it can be only be possible if i use [AcceptVerbs(HttpVerbs.Post)] with one function.
Can you please explain how does AcceptVerbs helps in overloading the function.What it actually does behind the scene?
And in one of my sample application i am able to overload the function by using [HttpPost] in one function.What else can be used for overloading?
Basically the rule is that you can handle this when it is responding to different types of requests, so Post/Get/Delete. (Any of the items in the HttpVerbs enumeration)
It is due to the way that it does resolution of the method to call in the controller, and specifying the method allows it to handle resolution.
In ASP.NET MVC, incoming request url should match action of controller. In MVC request processing pipeline, first the controller action is selected, and then the parameters for it are inspected and populated. Imagine what happened if controller had two methods with same name but different signature (overloaded).The c# compiler does not complain, as it understands the code, because it can distinguish between methods based on its parameter signature. But ASP.NET MVC request matching mechanism, as mentioned above, cannot - it first does search for action and only after action is selected, it takes look at its parameters. Because of this, "Public actions in controllers cannot be overloaded" - if there're no difference between methods(actions) other than parameters, action selection in MVC will fail to unambiguously select one. This's where ActionMethodSelectorAttribute comes into play. This is the base mechanism for developers to affect the way MVC searches for valid action in specified controller. It has the method IsValidForRequest() that tells MVC wether action can be selected for usage or not. All of [AcceptVerbs], [HttpGet], [HttpPost], [HttpPut], [HttpDelete] and [HttpNonAction] derive from this attribute. And bingo - now the method overloading is possible - although actions have got the same name, one of the attributes above (or your custom attribute derived from ActionMethodSelectorAttribute) can tell MVC wchich action to select and which one to not. And MVC now unambigously knows wchich action is valid for request. Consider example
[HttpGet]
public ActionResult Index()
{
// The above HttpGet.IsValidForRequest() called internally
by mvc will return true only if request is made via HTTP GET
}
[HttpPost]
public ActionResult Index(MyModel model)
{
// The above HttpPost.IsValidForRequest() called internally
by mvc will return true only if request is made via HTTP POST
}
// And so forth with other ActionMethodSelectorAttibute s. As you see, only one action from same named ones is valid for single request when decorated with any of builtin ActionMethodSelectorAttibute
Related
I would like to know the differences between a custom action filter and a custom action selector in ASP.NET MVC.
Say we want to restrict who can have access to an action method on a controller based on some rules. I could either create an action filter extending the ActionFilterAttribute class or extending the ActionMethodSelectionAttribute class, so that I could have something like:
[MyRestriction]
public ActionResult AnyAction(){}
Could anyone explain the differences between them so that I can make the right decision?
If you look at the documentation for ActionMethodSelectionAttribute, you will see at the very bottom of the page that there are a number of other classes that derive from this attribute.
These include:
Microsoft.Web.Mvc.AjaxOnlyAttribute
System.Web.Mvc.AcceptVerbsAttribute
System.Web.Mvc.HttpDeleteAttribute
System.Web.Mvc.HttpGetAttribute
System.Web.Mvc.HttpHeadAttribute
System.Web.Mvc.HttpOptionsAttribute
System.Web.Mvc.HttpPatchAttribute
System.Web.Mvc.HttpPostAttribute
System.Web.Mvc.HttpPutAttribute
System.Web.Mvc.NonActionAttribute
In other words, these are the attributes which control which Action Method is selected during routing when there are several different choices to choose from (ie there are 2 different Index methods, one decorated with [HttpGet] and one with [HttpPost]).
ActionFilterAttribute, on the other hand, is called only when an action is actually executing.
Think about it this way, The selection can run even if the action doesn't execute, the ActionFilter only runs if it does. The selection filter is only used to determine whether the action is a match condition, the action filter is used to do some action before, after, etc.. the action or response is executed.
What are the filters in asp.net mvc, can any one explain clearly.
How to create a custom filters in asp.net mvc 4
[Authorize]
Public ActionResults Index()
{
return View()
};
In ASP.NET MVC, controllers define action methods that usually have a one-to-one relationship with possible user interactions, such as clicking a link or submitting a form. For example, when the user clicks a link, a request is routed to the designated controller, and the corresponding action method is called.
Sometimes you want to perform logic either before an action method is called or after an action method runs. To support this, ASP.NET MVC provides action filters. Action filters are custom attributes that provide a declarative means to add pre-action and post-action behavior to controller action methods.
Check Filters-and-Attributes-in-ASPNET-MVC
The filter attribute has the Order property which can be used to manage the orders. The order needs to be the order the business process to be followed. For example if HandleError attribute is given higher order than the Authorize attribute then even an unauthorized users will be getting application errors. It would be better saying "Please Login".
ASP MVC WebGrid renders pagination links like
http://host/AnyController/AnyAction?Length=4&page=1
Any chance to parametrize or customize this to
http://host/AnyController/AnyAction/1
to conform better to MVC routing conventions?
(NOT important: btw Length is redundant. If the controller's Action method does not know the page length, by heart that's problem. )
Thanks in advance
One way to handle your default route conflict can be this, as most of the time when you use you route it will hit the action method without the [HttpGet]. All you need to do is a GET, whenever you sort or page the web gird, it will try to get data and hit the a HttpGet Action, this will work as follows:
[HttpGet]
public ActionResult YourActionMethod()
{
return PartialView("YourView",YourModel);
}
The best part is, upon sorting, the request will send a parameter named as "sortBy" too, you can use this here and decide what you want to do with the binded Model with the grid. You can inspect what URL the Sort header will hit by using the "Developer Tools" in your browser. You can use this action do as you will,
Note : By default the action method it would be hitting would be same as the controller name.
I'm sorry to ask such a basic question, but it's kind of fundamental for me. To better understand filters, I need to understand this notions. Although I'm on ASP.NET MVC for few months now and now are doing nice demos, I'm more familiar with Action method concept than action result.
What are:
Action Method?
Action Result?
How are they related?
Let's say I've this
public ViewResult ShowPerson(int id)
{
var friend = db.Persons.Where(p => P.PersonID == id).First();
return View(friend);
}
How those concepts apply to the above code?
Thanks for helping.
In your example ShowPerson is the action. Each action needs to return an action result (In your case it returns a view). So when a controller action method is invoked it does some processing and decides what view would be best adapted to represent the model.
There are many different action results that you might use. They all derive from ActionResult:
ViewResult - if you want to return a View
FileResult - if you want to download a file
JsonResult - if you want to serialize some model into JSON
ContentResult - if you want to return plain text
RedirectResult - if you want to redirect to some other action
HttpUnauthorizedResult - if you want to indicate that the user is not authorized to access this action
FooBarResult - a custom action result that you wrote
Answer by #Darin-dimitrov is very much upto the point. But I see explanation given on MSDN also very much helpful.
Action methods typically have a one-to-one mapping with user
interactions. Examples of user interactions include entering a URL
into the browser, clicking a link, and submitting a form. Each of
these user interactions causes a request to be sent to the server. In
each case, the URL of the request includes information that the MVC
framework uses to invoke an action method.
When a user enters a URL into the browser, the MVC application uses
routing rules that are defined in the Global.asax file to parse the
URL and to determine the path of the controller. The controller then
determines the appropriate action method to handle the request. By
default, the URL of a request is treated as a sub-path that includes
the controller name followed by the action name. For example, if a
user enters the URL http://contoso.com/MyWebSite/Products/Categories,
the sub-path is /Products/Categories. The default routing rule treats
"Products" as the prefix name of the controller, which must end with
"Controller" (such as ProductsController). It treats "Categories" as
the name of the action. Therefore, the routing rule invokes the
Categories method of the Products controller in order to process the
request. If the URL ends with /Products/Detail/5, the default routing
rule treats "Detail" as the name of the action, and the Detail method
of the Products controller is invoked to process the request. By
default, the value "5" in the URL will be passed to the Detail method
as a parameter.
What is the point of an action returning ActionResult?
Returning an ActionResult instead of "just doing whatever the ActionResult is doing" (i.e. using Response.Redirect directly or trying to render out a View through the Response OutputStream directly) gives you one really nice advantage: Unit Testing is really easy on that, especially since you normally do not need a web server to unit test MVC Projects.
Addendum: As an example for a redirect:
If you do
return Redirect(newUrl);
in your controller, your Unit Test can now
Verify that the return value is of Type "RedirectResult"
Look at the URL that is being redirected to by checking result.Url after casting it to RedirectResult
All without having to spin up IIS or trying to "clevery" intercept the Response.Redirect call
At the end of the day, RedirectResult calls Response.Redirect in it's ExecuteResult function, but your Controller Unit Test sits in front of that
Addendum 2: And while I am on it, here is an example of a Custom ActionResult:
http://www.stum.de/2008/10/22/permanentredirectresult/
This is just to show that they are not "Black Magic". They are actually pretty simple: Your Controller returns an Action Result, and the MVC Runtime will eventually call the ExecuteResult function on it, passing in a ControllerContext that your ActionResult can interact with. The whole point again is to separate the parts of M-V-C, to make Code Reusable, and to make Unit testing easier, or in short: To give a very clean Framework.
Since it is the base class, it allows you to return any of the ActionResult subclasses, such as ViewResult or JsonResult. I typically return ViewResult as the default, but override that behavior if I am dealing with Ajax to return a JsonResult object.
This allows me to add Ajax as a progressive enhancement and keep the application working without JavaScript and without the need for separate controller actions.
ActionResult is the base class for many different types of controller results. By returning the base class, the controller action can return different types of results depending on the outcome of the method -- a ViewResult, a RedirectToActionResult, etc. ActionResult contains all of the data needed by the View or new Action that is the result of the current controller action.