If a user requests an URL then the ASP.NET MVC framework maps URLs to classes that are referred to as Controllers. Controllers process incoming requests using action methods. Action methods typically have a one-to-one mapping with user interactions. 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. As per MSDN, a method must meet the following requirements:
- The method must be public.
- The method cannot be a static method.
- The method cannot be an extension method.
- The method cannot be a constructor,getter, or setter.
- The method cannot have open generic types.
- The method is not a method of the controller base class.
- The method cannot contain ref or out parameters
We can create action methods that return an object of any type, such as a string, an integer, or a Boolean value. These return types are wrapped in an appropriate ActionResult type before they are rendered to the response stream. The ASP.NET MVC framework will convert any return type that is not an action result into a string and render the string to the browser. Create a simple controller as in the following code snippet:
- public class HomeController : Controller
- {
- public ActionResult SayHello()
- {
- ViewData["SayHello"] = "Hello";
- return View();
- }
- public string SayHi()
- {
- return "hi from 'SayHi'.";
- }
-
- }
We must create a view to run SayHello() since it returns the View as views\home\ SayHello.cshtml. To execute second action method we don’t need to create a view. It will render the string in the browser. We can also have a void public method as an action method. So we can say any public method can be an action method.
We can make a public function a non-action by decorating it with [NonAction] as in the following:
- [NonAction]
- public string SayHi()
- {
- return "hi from 'SayHi'.";
- }
Getting Results
The successful execution of an MVC controller action will produce an object derived from ActionResult. Rendering a view and redirecting the browser to a new URL are both valid types of results we can get from our controller. The complete list of ActionResult derived types that can be an output of action method are as follows.
Name |
Framework Behavior |
Producing Method |
ContentResult |
Writes a string value directly into the response. |
Content |
EmptyResult |
Blank HTTP response. |
|
FileContentResult |
Takes the contents of a file (represented as an array of bytes) and writes the contents into the HTTP response. |
File |
FilePathResult |
Takes the contents of a file at the given location and writes the contents into the HTTP response. |
File |
FileStreamResult |
Takes a file stream produced by the controller and writes the stream into the HTTP response. |
File |
HttpUnauthorizedResult |
A special result used by authorization filters when authorization checks fail. |
|
JavaScriptResult |
Responds to the client with a script for the client to execute. |
JavaScript |
JsonResult |
Responds to the client with data in JavaScript Object Notation (JSON). |
JSON |
RedirectResult |
Redirects the client to a new URL. |
Redirect |
RedirectToRouteResult |
Renders the specified view to respond with an HTML fragment (typically used in AJAX scenarios). |
RedirectToRoute / RedirectToAction |
PartialViewResult |
Renders the specified view to respond with an HTML fragment (typically used in AJAX scenarios). |
PartialView |
ViewResult |
Renders the specified view and responds to the client with HTML. |
View |
Overloading
MVC supports the method overloading but it doesn't support method overloading based solely on signature, so this will fail. If we have two actions like the following then it fails.
- public string SayHello()
- {
- return "Hello from 'SayHello'.";
- }
- public string SayHello(string name)
- {
- return "Hello " + name + " from 'SayHello' ";
- }
We need to decorate our action method with two attributes, like [HpptGet] and [HttpPost]. We can use the ActionName attribute to expose two methods with the same name as actions with different names.
- public class HomeController : Controller
- {
- [ActionName("SayHelloWithOutName")]
- public string SayHello()
- {
- return "Hello from 'SayHello(SayHelloWithOutName)'.";
- }
- public string SayHello(string name)
- {
- return "Hello " + name + " from 'SayHello' ";
- }
- public string SayHi()
- {
- return "hi from 'SayHi'.";
- }
- }
We can create our own ActionFilter derived from ActionMethodSelectorAttribute. Here we are checking the URL parameter then invoke the appropriate method.
- public class MyActionSelectorAttribute : ActionMethodSelectorAttribute
- {
- public MyActionSelectorAttribute(string valueName)
- {
- ValueName = valueName;
- }
- public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
- {
- return (controllerContext.HttpContext.Request[ValueName] != null);
- }
- public string ValueName { get; private set; }
- }
We need to decorate our method with the parameter MyActionSelectorAttribute as in the following code snippet:
- public string SayHello()
- {
- return "Hello from 'SayHello'.";
- }
- [MyActionSelectorAttribute("name")]
- public string SayHello(string name)
- {
- return "Hello " + name + " from 'SayHello' ";
- }