[Original address] ASP. net mvc Framework (Part 2): URL Routing
[Original article publication date] Monday, December 03,200 AM
Last month, I published the first article in my series of posts, which will discuss the new ASP. NET MVC framework we are developing. The first post in this series creates a simple e-commerce product list/browsing scenario, discusses the high-level concepts behind MVC, and demonstrates how to create a new ASP. net MVC project to implement and test the e-commerce product list function.
In today's post, I will discuss ASP in depth. net MVC Framework's routing architecture, discusses some cool customization methods, you can use it in some more advanced scenarios in your application.
Brief description of the First Part
In the first part of this series, we created an e-commerce website with three types of URLs:
URL format |
Action |
URL example |
/Products/Categories |
Browse all product categories |
/Products/Categories |
/Products/LIST/Category |
List products in a category |
/Products/LIST/beverages |
/Products/detail/Productid |
Display details of a specific product |
/Products/detail/34 |
We create a productscontroller class like the following to process these URLs:
After adding the above class to our application, the ASP. Net MVC Framework will automatically direct the incoming URL to the appropriate action Method on our controller to process the request.
In today's post, we will discuss in depth how this URL ing HAPPENS, and how we can use ASP.. Net MVC framework uses more advanced routing scenarios. I will also demonstrate how you can easily unit test URL path selection scenarios.
What do ASP. net mvc url path selection systems do?
The ASP. Net MVC framework includes a flexible URL path selection system that allows you to define URL ing rules in applications. The path selection system has two main objectives:
- Map the incoming URLs to the application and direct them to the application. In this way, the correct controller and action method are executed to process these requests.
- Construct the URL that can be used to call back the output of controllers/actions to the client (for example, form submission, <a href = ""> link, and Ajax call)
The ability to use URL ing rules to simultaneously process incoming and output URL scenarios for the ApplicationCodeAdded a lot of flexibility. This means that if we want to change the URL structure of an application in the future (for example, rename/products to/Catalog), we can modify a set of ing rules at the application level, you do not need to modifyAnyCode.
Default ASP. net mvc url path selection rules
By default, when you use Visual Studio to create a new project using the ASP. net mvc Web Application Template, it adds an ASP. NET application class to the project. This is implemented in the global. asax background code:
The ASP. NET application class allows developers to handle application startup/abort and global error handling logic.
The default ASP. Net MVC Project template automatically adds an application_start Method to the class and registers two URL path selection rules:
The first path selected in the preceding rule indicates that ASP. by default, the net MVC Framework determines which controller class is used to generate instances and which action method is called (and which parameters need to be passed in ), you should map the URL to the Controller in the format of "[controller]/[action]/[ID.
The default path selection rule is why the URL/products/detail/3 requests in our e-commerce browsing routine in the first part automatically call the detail method of our productscontroller class, the reason why 3 is passed as the ID parameter value:
The second path selection rule above is used for the root URL "default. aspx "performs special processing (when processing the request of the root URL of an application, this URL is sometimes passed in by the server instead ). This rule ensures the root "/default. aspx "or"/"requests will be initiated by the homecontroller class (when we use ASP. net MVC Web Application Project template to generate a new application, the index () Action method is processed in the Controller automatically generated by Visual Studio.
Understanding route instances
The path selection rule is registered by adding a route instance to the routes set of system. Web. MVC. routetable.
The route class defines many attributes that you can use to configure ing rules. You can set these attributes by assigning values to the "traditional". NET 2.0 attributes:
Alternatively, you can use the new object initializer features in the C # and VB compilers of vs 2008 to set attributes more concisely:
The URL attribute of the route class defines whether a path selection rule applies to the URL matching rules of specific incoming requests. It also defines how the URL should be split into different parameters (tokenized. Parameters that can be replaced in a URL are defined by the [parameter name] syntax. As mentioned in post-literary theory, we are not limited to a set of fixed "well-known" parameter names. You can use any number of parameters in the URL. For example, I can use a "/blogs/[username]/archive/[year]/[month]/[Day]/[title]" url rule to post a blog separate URLs, the MVC Framework automatically analyzes the parameters username, year, month, day, and title, and passes them into the Action Method of my controller.
The ults attribute in the route class defines a default value dictionary, which can be used when the incoming URL does not contain a specified parameter value. For example, in the preceding URL ing example, we define two default URL parameter values: "[action]" and "[ID]". This means that if the application receives the/products/url, by default, the system uses "Index" as the action name of productscontroller by default. Similarly, if/products/LIST/is specified, the Null String is used as the value of the "ID" parameter.
The routehandler attribute of the route class defines the iroutehandler instance used to process requests after the URL is divided into parameters and the appropriate path selection rule is determined. In the above example, we show that we want to use the system. Web. MVC. mvcrountehandler class to process the configured URL. The reason for this additional step is that we want to ensure that the URL path selection system can be used for both MVC and non-MVC requests. With this iroutehandler interface, we can also use it cleanly for non-MVC requests (such as standard webforms And Astoria rest support ).
The route class also has a validation attribute, which will be discussed later in this article. This attribute allows us to specify a prerequisite for matching the path selection rule. For example, we can specify a path selection rule that should only apply to a specific HTTP verb (allow us to easily map REST commands), or we can use regular expressions for parameter values, to filter whether a path selection rule matches.
Note: In the first public preview version of the MVC Framework, the route class cannot be extended (it is only a data class). In the next preview version, we are studying how to make it extensible, allowing developers to add path classes for specific scenarios (for example, a restroute subclass) to add new semantics and functions cleanly.
Path rule Evaluation
When an incoming URL is received by an ASP. net mvc web application, the MVC framework evaluates the path selection rules in the routetable. routes set to determine the appropriate controller to process the request.
The MVC framework evaluates the Controller to be used in the order of registration by routetable rules. Check the incoming URL for each route rule to see if it matches. If a route rule matches, the rule (and associated routehandler) will be used to process incoming requests (all subsequent rules are omitted ). This means that you generally need to organize your path selection rules in the order of "the most special to the least special (most specific to least specpacific, from special to general.
Path Selection scenario: Custom query URL
Let's use the custom path selection rules in actual scenarios to demonstrate this process. The following uses the query function of our e-commerce website as an example.
At the beginning, we will add a new searchcontroller class to our project:
Then, we define two action methods in the searchcontroller class. The index () method is used to display a query page with a text box on which users can enter and submit query text. The results () Action method is used to process the corresponding form submission, query the database, and display the result to the user:
Use the default/[Controller]/[action]/[ID]URL path ing rules, we can use a URL like the following to call our searchcontroller behavior:
Scenario |
URL |
Action Method |
Query Form: |
/Search/ |
Index |
Query results: |
/Search/results? Query = beverages |
Results |
|
/Search/results? Query = ASP. NET |
Results |
Note that the root URL/search is mapped to the index () Action Method by default because when Visual Studio creates a new project, the default path definition of/[controller]/[action]/[ID] is used to automatically set the default action to "Index" (through the defaults attribute ):
Although/Search/results? Query = beveragesSuch a URL is completely feasible. We may decide that we want a URL that looks better than the query results. Specifically, we may want to remove the "Results" action name in the URL and pass in the text to be queried as part of the URL, rather than as the value of the URL query string. For example:
Scenario |
URL |
Action Method |
Query Form: |
/Search/ |
Index |
Query results: |
/Search/beverages |
Results |
|
/Search/ASP. NET |
Results |
In the default/[controller]/[action]/[ID] ruleBeforeAdd two custom URL path ing rules to enable these nice query result URLs, as shown below:
In the first two rules, the Controller and action parameters of the corresponding/search/URL are clearly specified. We show that "/search" should always be handled by the "Index" action on the searchcontroller. All URLs (/search/Foo,/search/bar, etc.) with sub-URL hierarchies are always processed by the "Results" action on the searchcontroller.
The second path selection rule above indicates that any character after the/search/prefix should be treated as a parameter named "[query, this parameter will be used as a method parameter to pass in the Results Action Method on searchcontroller:
Most likely, we also enable pagination for the query results (we only display 10 query results each time. We can query string values (for example,/search/beverages? Page = 2), or we can embed the page number in a URL (for example,/search/beverages/2 ). To support the following method, we need to add an additional saving parameter to our second path selection rule:
Note that the new URL rule above matches "Search/[query]/[Page]". We also set the default page number to 1, in case the page number is not included in the URL (this is passed through as the anonymous type of the "defaults" attribute value ).
Then, we can update our searchcontroller. Results Action Method to accept the page number parameter as a method parameter:
In this way, we have a better-looking query URL (the rest is to implement this queryAlgorithm, I will leave it as an exercise for the reader to complete ).
Prerequisite for verifying the path selection rule
As I mentioned earlier in this post, the route class has a validation attribute that allows you to add rules for matching paths, the prerequisite rules must be verified (except for URL filtering ). The ASP. net mvc framework allows you to use regular expressions to verify the parameter values in a URL. You can also evaluate HTTP headers (select different URL Paths Based on the HTTP verb ).
The following is a custom verification rule that can be used on a URL such as/products/detail/43. It specifies that the ID parameter must be a number (a string is not allowed ), and its length must be between 1 and 8:
If we input a URL like/products/detail/12 to the application, the above path selection rule is valid, however, if/products/detail/ABC or/products/detail/23232323232 is input, it will not match.
Select the URL of the system build output from the path
Before this article, I have mentioned that the URL path selection system in the ASP. NET MVC framework is responsible for two tasks:
- Map the entered URL to the controllers/actions to be processed.
- This helps construct the URL that can be used to call back the output of controllers/actions to the client later (for example, form submission, <a href = ""> link, and Ajax call)
There are many auxiliary methods and classes in the URL path selection system, so that you can dynamically view and construct the URL at runtime (you can also directly view the URL of the routetable route set ).
Html. actionlink
In the first part of this blog series, I briefly discussed the HTML. actionlink () view auxiliary methods. It can be used in a view, allowing you to dynamically generate <a href = ""> hyperlinks. What's cool is that it can use the MVC path to select the URL ing rules defined in the system to generate these URLs. For example, the following two html. actionlink calls:
Automatically pick up the special search results route rule we configured earlier in this post, and the "href" attribute they generate automatically reflect this: the special query result path rules we configured before this post are automatically used. The href attributes automatically generated by these rules reflect this situation:
Pay attention to the preceding HTML. the second call of actionlink automatically maps the page parameter to a part of the URL (note that the value of the page parameter is omitted in the first call because it knows that the server will automatically provide the default value ).
URL. Action
In addition to HTML. actionlink, ASP. net mvc also provides an auxiliary URL. Action () view method. This method generates native string URLs, and you can use them in any way. For example, the following code snippet:
The system returns the following native URL (instead of wrapped in the <a href = ""> element) using the URL path ):
Controller. redirecttoaction
ASP. net mvc also provides the controller. redirecttoaction () method. You can use it in the Controller to perform the redirection operation (the URL is calculated by using the URL path selection system ).
For example, when the following code is called in the controller:
Internally, it generates a call to response. Redirect ("/search/beverages.
Dry (do not repeat yourself)
The advantage of all of the above auxiliary methods is that they allow us to avoid hard URL writing in our controller and view logic. If we decide to change the URL path ing rule later, change from "/search/[query]/[Page]" to "/search/results/[query]/[Page]" or "/search/results? Query = [query] & page = [Page] ". You can easily edit it in one place (in our path Registration Code. We can pick up a new URL without modifying any code in the view or controller (this sticks to the "dry principle ").
Use lambda expressions to select the URL of the system to build the output from the path
The preceding URL helper method uses the new anonymous types currently supported by VB and C # In vs 2008. In the preceding example, an anonymous type is used to effectively input a string of name/value pairs, to help map URLs (you can think of this as a clean way to generate dictionaries ).
ASP. net MVC framework also supports the ability to create action paths using the strong type mechanism, which provides URL-assisted methods with checking at compilation and intelliisense. This is achieved through the use of generics and the new VB and C # support for lambda expressions.
For example, the following anonymous actionlink call:
You can also write it as follows:
In addition to writing briefly, this second option also has the benefits of type security, this means that you get the expression compilation check and Visual Studio code intelliisense (you can also use the refactoring tool to refactor it ):
Note that the preceding figure shows how to use intelliisense to select the Action Method of searchcontroller and the parameters are strongly typed. The generated URLs are all driven by the ASP. net mvc url selection system.
You may be wondering, what is the problem? If you still remember, eight months ago, when I talked about lambda expressions in my blog, I talked about lambda expressions that can be compiled into code proxies (delegate ), it can also be compiled into an Expression Tree object, which can be used to analyze lambda expressions at runtime. For HTML. actionlink <t> auxiliary method. We use this expression tree option and analyze the corresponding Lambda at runtime to find out the called Action method and related parameter types, the name and value specified in the expression. Then we can use this information in the mvc url path selection system to return the appropriate URL and associated HTML.
Important Notes: When using this Lambda expression method, we never actually run the corresponding controller action method. For example, the following codeNoCall the "Results" Action Method in our searchcontroller:
In fact, it only returns the HTML hyperlink:
If this hyperlink is clicked by a user, it will send a request to the server, which will call the Results Action Method of searchcontroller.
Unit Test path
A core design principle of ASP. net mvc framework is to promote good test support. Like other parts of the MVC framework, you can easily configure the path and Path Matching rules for unit tests. The MVC path selection system can be independent of ASP. net to generate instances and run them. This means that you can load and run the unit test path mode in any unit test Library (instead of starting the Web server). You can use any unit test framework (nunit, mbunit, mstest and so on ).
Although you can directly test an ASP in your unit test. net MVC application global routetable able ing set, but in general, it is not a good idea to change the unit test or depend on a global state. A better mode you can use is to put your path registration logic in a registerroutes () auxiliary method like below to operate the routecollection passed as a parameter (note: we may make this mode the default vs template mode in the next preview version update ):
Then, you can write a unit test, create your own routecollection instance, call the registerroutes auxiliary method of the application, and register the application path selection rules. Then, you can send a simulated request to the application to verify that these requests have registered the correct controller and action methods without worrying about any side effects:
Conclusion
I hope this post provides information about ASP. net MVC path to select some details about the working principle of the architecture, and how you can use it to customize the release in your asp.. Net MVC application URL structure and layout.
By default, you can create a new ASP. net MVC web application, it will pre-define a default/[controller]/[action]/[ID] path selection rule that you can use, you do not have to manually configure or enable anything. This should allow you to build many applications without registering your own custom path selection rules. But I hope the above content will be demonstrated. If you want to customize the structure of your own URL format, it is not difficult to do it. The MVC Framework provides many functions and flexibility for this.