Use the IController interface to complete a default route for the controller:
routes.MapRoute( name: "Default", url:"{controller}/{action}/{id}", defaults: new { controller ="Home", action = "Index", id = UrlParameter.Optional } );
Add controller:
public void Execute(RequestContextrequestContext) { var controller = (string)requestContext.RouteData.Values["controller"]; var action =(string)requestContext.RouteData.Values["action"]; requestContext.HttpContext.Response.Write( string.Format("Controller: {0}, Action: {1}", controller,action)); }
Access controller to view the result:
This is the simplest way to create a controller, but this is usually not done because:
What we get is the RequestContext object. We need to manually generate html and write it to Response to return the client, and the code will be difficult to maintain.
Integrates the Controller class to complete a controller
Generally, every time we create a new controller, the controller class is automatically inherited. This class mainly helps us accomplish two things:
1. Get the requestContext object from the route, parse the action and parameters, and call
2. provide different results (command mode) and return them to the client.
In addition, we can also use filter to complete the concern of different crosscutting, which will be detailed in later sections.
The introduction of the concepts of action and result makes it easier for our code to perform unit tests. At least it is much easier to directly operate the RequestContext object than to inherit the IController interface.
Controller example:
public class DerivedController :Controller {public ActionResult Index() {ViewBag.Message = "Hellofrom the DerivedController Index method";return View("MyView");}}
View code:
@{ViewBag.Title ="MyView";}MyViewMessage: @ViewBag.Message
The code is very simple, that is, to use Viewbag to pass the value to the View display, the Controller returns the most common result, ViewResult.
How to Get client value transfer from controller
1. Extract directly from context object
2. Pass in through parameters (resolution is completed by the base class controller)
3. Use model binding
Common objects of context object
Request. QueryString |
Retrieve from the Get request url |
Request. Form |
Retrieve from the form in the Post request |
Request. Cookies |
Put the value in the cookie of the request. |
RouteData. Route |
Obtain the registered route name from the route table. |
RouteData. Values |
Obtain the anonymous object of the route configuration from the route table |
HttpContext. Cache |
Application Cache |
HttpContext. Items |
Store some values and use them only in the same request (you can pass values in different modules, handler, and pages of the httppipeline process) |
HttpContext. Session |
Session of the current user |
TempData |
Save some temporary values, which will be automatically deleted after Removal |
In addition, it is not recommended to directly retrieve the parameter Values from RouteData. Values:
public ActionResult ShowWeatherForecast() {string city =(string)RouteData.Values["city"];DateTime forDate =DateTime.Parse(Request.Form["forDate"]);return View(forDate);}
We recommend that you rewrite it as parameter passing:
public ActionResult ShowWeatherForecast(string city, DateTime forDate) {return View(forDate);}
For parameter passing, note:
1. For the reference type, if RouteData does not obtain the parameter, null is given. To avoid receiving null, you can use the default parameter.
2. If no parameter is obtained for the value type, an exception is thrown. Therefore, we recommend that you provide the default parameter for the value type or use the Nullable type.
For example:
public ActionResult Search(stringquery= "all", int page = 1) {// ...process request...return View();}
Execute Result
Controller's responsibilities:
1. Operate domain model
2. Return a suitable result
After the domainmodel operation is completed, the result will be returned to the client. It is not recommended to manually implement the IController interface for Redirect or direct Response. Write Data to the client. As mentioned earlier:
1. Directly output html or directly jump to the url, reducing readability and maintainability
2. unit testing is difficult.
3. Difficult to get started with the handover
Use ActionResult
The controller of MVC Framework has provided us with sufficient result types to return to the client for interaction. To understand ActionResult, first customize one:
public class CustomRedirectResult: ActionResult {public string Url { get; set; }public override void ExecuteResult(ControllerContextcontext) {string fullUrl =UrlHelper.GenerateContentUrl(Url, context.HttpContext);context.HttpContext.Response.Redirect(fullUrl);}}
To customize a result, the ActionResult must be inherited to implement the ExecuteResult method. MVCFramework provides us with a controllerContext object, which contains enough information we need. The actionResult function created above: Specifies a url, get the controllerContext object and generate a fullurl to complete the jump.
Use this result:
public ActionResult ProduceOutput() {if (Server.MachineName == "IORI"){return new CustomRedirectResult {Url = "/Basic/Index" };} else {Response.Write("Controller:Derived, Action: ProduceOutput");return null;}}
Common results:
ViewResult |
Returns a view. You can specify different controllers. |
ParcialViewResult |
Return partial view |
RedirectToActionResult |
Go to another action |
RedirectResult |
Returns 301 or 302 (permanent) |
JsonResult |
Return js's favorite json, which is commonly used. In particular, the current section uses a pure js template or a single page application. |
FileResult |
File result |
ContentResult |
String |
HttpUnauthorizedResult |
401. Generally, the logon page is automatically displayed. |
HttpNotFoundResult |
404 |
When viewResult is returned, the query order is as follows:
1./Views/ / . Aspx
2./Views/ / . Ascx
3./Views/Shared/ . Aspx
4./Views/Shared/ . Ascx
5./Views/ / . Cshtml
6./Views/ / . Vbhtml
7./Views/Shared/ . Cshtml
8./Views/Shared/ . Vbhtml
As you can see, mvcframework will first start from the familiar aspx and ascx
Directly transfer the path and return the specified view
public ViewResult Index() {return View("~/Views/Other/Index.cshtml");}
If there is code similar to the above, consider two issues:
Want to jump to another action? You can consider using RedirectToAction.
Is the View misplaced?
Send the value of Action to ViewModel Object
public ViewResult Index() {DateTime date = DateTime.Now;return View(date);}
View:
@model DateTime@{ViewBag.Title ="Index";}IndexThe day is: @Model.DayOfWeek
ViewBag
public ViewResult Index() {ViewBag.Message ="Hello";ViewBag.Date = DateTime.Now;return View();}
View:
@{ViewBag.Title ="Index";}IndexThe day is:@ViewBag.Date.DayOfWeekThe message is: @ViewBag.Message
Advantages of ViewBag:
You can directly pass the object without defining the type and passing any object.
Disadvantages:
Errors are always run, because they are DynamicObject (DynamicViewDataDictionary actually inherits from DynamicObject, so it can be dynamically expanded like other functionlanguage languages)
Redirect to the specified urlHttpStatusCode: 302 (temporary redirect)
public RedirectResult Redirect(){return Redirect("/Example/Index");}
HttpStatusCode: 301 (permanent redirection, careful, not commonly used)
public RedirectResult Redirect(){return RedirectPermanent("/Example/Index");}
Jump back to route
public RedirectToRouteResult Redirect() {return RedirectToRoute(new {controller = "Example",action = "Index",ID = "MyID"});}
In most cases, when a request cannot be processed, we can at least determine the controller and action to jump:
public RedirectToRouteResult RedirectToRoute() {return RedirectToAction("Index");}
You can specify the controller:
public RedirectToRouteResult Redirect() {return RedirectToAction("Index", "Basic");}
Value transmitted during Redirection
In MVCframework, the ideal choice is to use TempData:
Assignment:
public RedirectToRouteResult RedirectToRoute() {TempData["Message"] ="Hello";TempData["Date"] =DateTime.Now;return RedirectToAction("Index");}
Valid value:
public ViewResult Index() {ViewBag.Message =TempData["Message"];ViewBag.Date =TempData["Date"];return View();}
The advantage of this object is that it is marked as removable after it is obtained, and will be cleared automatically after the request is completed. If you want to retrieve the data multiple times, you can use the peek method (but we recommend that you clear the data for the last time (using the index )):
TempData. Peek ("Date ");
In addition, I also recommend HttpRequest. Items, which is also a good choice for passing values in httppipeline.
Return httpstatus code
404 (the url cannot be found ):
public HttpStatusCodeResult StatusCode() {return new HttpStatusCodeResult(404, "URL cannot be serviced");}
401 (restricted access permissions ):
public HttpStatusCodeResult StatusCode() {return new HttpUnauthorizedResult();}