Using ASP. NET Web Api to build a restful service practice series of tutorials -- Attribute Routing

Source: Internet
Author: User

Digress: This technical point is newly learned and does not belong to the original series. However, with the help of the Project Background of the original series, the external series is named, some new technologies may be added to this series in the future. In Web Api 2.0, A New Route configuration method is proposed-Attribute-based Routing ), the configuration Routing method we introduced earlier is called Convention-based Routing. The new Routing configuration method is also applied in MVC5, therefore, this article will introduce the feature-based routing. In the previous article, we handled such a business-implementing the Course Selection for students. We have customized a route data in "WebApiConfig". This route enables you to select a course and query all the student information selected for this course based on the course Id, I think the design is okay. In practical applications, query is generally used most often. Using Attribute Routing to register a route is more flexible, easier to control, and better compliant with Rest. This document describes the information of all students who select the course and the information of a student based on the Course name and Student name. As the name suggests, a new route provider uses a feature to register a route. For example, copy the Code [AttributeUsage (AttributeTargets. method | AttributeTargets. class, AllowMultiple = true, Inherited = true)] public sealed class RouteAttribute: Attribute, IHttpRouteInfoProvider {public RouteAttribute (); public RouteAttribute (string template); public string Name {get; set;} public int Order {get; set;} public string Template {get; private set ;}} copy the code package There are three attributes: Name indicates the Name of the route, and Order indicates the route Order, template is something that we need to match the URL Template to implement the principle of Attribute Routing. There is not much to introduce (I have not studied much). We can only apply the learned technology to reality, A large number of principles are easy to faint, so we need to study them further in the future. Add a new method GetStudentsInfo in "EnrollmentsController": copy the Code [Route ("api/enrollments/{courseName}/{studentName ?} ")] Public IEnumerable <StudentBaseModel> GetStudentsInfo (string courseName, string studentName =" ") {IQueryable <Student> query; Course course = TheRepository. getAllCourses (). where (c => c. name = courseName ). firstOrDefault (); if (course = null) {return null;} query = TheRepository. getEnrolledStudentsInCourse (course. id ). orderBy (s => s. lastName); if (! String. isNullOrWhiteSpace (studentName) {query = query. where (s => s. firstName = studentName);} var totalCount = query. count (); System. web. httpContext. current. response. headers. add ("X-InlineCount", totalCount. toString (); var results = query. toList (). select (s => TheModelFactory. create (s); return results;} the copied Code uses RouteAttribute on our Action. Analyze the URL template ("api/enrollments/{courseName}/{studentName ?} "), {CourseName} will match the courseName parameter of the Action. Another parameter of the Action, studentName, is an optional parameter. That is, if no value is provided in the request, it is the default null string, if it is worth it, it will be assigned a value. So we add it after "{studentName? Mark as an optional URI parameter. OK, it's that simple. Test Once: image result: image er, error... A new problem has an error, but the solution is always there anyway. First, let's take a look at the cause of the error: There is an empty reference in the method of the LearningControllerSelector class, so we have to look at this method: copy the code public override HttpControllerDescriptor SelectController (HttpRequestMessage request) {var controllers = GetControllerMapping (); // Will ignore any controls in same name even if they are in different namepsace var routeData = request. getRouteData (); var controllerName = routeData. values ["controller"]. toString (); HttpControllerDescriptor controllerDescriptor; if (controllers. tryGetValue (controllerName, out controllerDescriptor) {var version = "2"; var versionedControllerName = string. concat (controllerName, "V", version); HttpControllerDescriptor versionedControllerDescriptor; if (controllers. tryGetValue (versionedControllerName, out versionedControllerDescriptor) {return versionedControllerDescriptor;} return controllerDescriptor;} return null ;} after reading the code, we can easily find that this method overwrites the base class method to implement current version control (details can be moved: http://www.cnblogs.com/fzrain/p/3558765.html In the method we override, we use the name of the Controller contained in RouteData, which is obtained by matching the routing and URI based on the Convention, therefore, we certainly do not have one here. Because our project has a mix of 2-minute route configurations, and the custom method is for convention-based Routing configuration, we use the default option for Attribute Routing: in "var controllerName = routeData. values ["controller"]. toString (); "add a judgment before the code: if (string. isNullOrWhiteSpace (routeData. route. routeTemplate) {return base. selectController (request);} the following result is returned when the request is made again: The image result is correct, and the solution may be considered again. Do you have any suggestions. However, either way, it is clear that for feature-based routing rules, the name of the Controller does not need to be included, in this case, we find the routing template on Acton to match the request URI, and then determine the corresponding Action. Digress: This technical point is newly learned and does not belong to the original series. However, with the help of the Project Background of the original series, the external series is named, some new technologies may be added to this series in the future. In Web Api 2.0, A New Route configuration method is proposed-Attribute-based Routing ), the configuration Routing method we introduced earlier is called Convention-based Routing. The new Routing configuration method is also applied in MVC5, therefore, this article will introduce the feature-based routing. In the previous article, we handled such a business-implementing the Course Selection for students. We have customized a route data in "WebApiConfig". This route enables you to select a course and query all the student information selected for this course based on the course Id, I think the design is okay. In practical applications, query is generally used most often. Using Attribute Routing to register a route is more flexible, easier to control, and better compliant with Rest. This document describes the information of all students who select the course and the information of a student based on the Course name and Student name. As the name suggests, a new route provider uses a feature to register a route. For example, copy the Code [AttributeUsage (AttributeTargets. method | AttributeTargets. class, AllowMultiple = true, Inherited = true)] public sealed class RouteAttribute: Attribute, IHttpRouteInfoProvider {public RouteAttribute (); public RouteAttribute (string template); public string Name {get; set;} public int Order {get; set;} public string Template {get; private set ;}} copy the code package There are three attributes: Name indicates the Name of the route, and Order indicates the route Order, template is something that we need to match the URL Template to implement the principle of Attribute Routing. There is not much to introduce (I have not studied much). We can only apply the learned technology to reality, A large number of principles are easy to faint, so we need to study them further in the future. Add a new method GetStudentsInfo in "EnrollmentsController": copy the Code [Route ("api/enrollments/{courseName}/{studentName ?} ")] Public IEnumerable <StudentBaseModel> GetStudentsInfo (string courseName, string studentName =" ") {IQueryable <Student> query; Course course = TheRepository. getAllCourses (). where (c => c. name = courseName ). firstOrDefault (); if (course = null) {return null;} query = TheRepository. getEnrolledStudentsInCourse (course. id ). orderBy (s => s. lastName); if (! String. isNullOrWhiteSpace (studentName) {query = query. where (s => s. firstName = studentName);} var totalCount = query. count (); System. web. httpContext. current. response. headers. add ("X-InlineCount", totalCount. toString (); var results = query. toList (). select (s => TheModelFactory. create (s); return results;} the copied Code uses RouteAttribute on our Action. Analyze the URL template ("api/enrollments/{courseName}/{studentName ?} "), {CourseName} will match the courseName parameter of the Action. Another parameter of the Action, studentName, is an optional parameter. That is, if no value is provided in the request, it is the default null string, if it is worth it, it will be assigned a value. So we add it after "{studentName? Mark as an optional URI parameter. OK, it's that simple. Test Once: image result: image er, error... A new problem has an error, but the solution is always there anyway. First, let's take a look at the cause of the error: There is an empty reference in the method of the LearningControllerSelector class, so we have to look at this method: copy the code public override HttpControllerDescriptor SelectController (HttpRequestMessage request) {var controllers = GetControllerMapping (); // Will ignore any controls in same name even if they are in different namepsace var routeData = request. getRouteData (); var controllerName = routeData. values ["controller"]. toString (); HttpControllerDescriptor controllerDescriptor; if (controllers. tryGetValue (controllerName, out controllerDescriptor) {var version = "2"; var versionedControllerName = string. concat (controllerName, "V", version); HttpControllerDescriptor versionedControllerDescriptor; if (controllers. tryGetValue (versionedControllerName, out versionedControllerDescriptor) {return versionedControllerDescriptor;} return controllerDescriptor;} return null ;} after reading the code, we can easily find that this method overwrites the base class method to implement current version control (details can be moved: http://www.cnblogs.com/fzrain/p/3558765.html In the method we override, we use the name of the Controller contained in RouteData, which is obtained by matching the routing and URI based on the Convention, therefore, we certainly do not have one here. Because our project has a mix of 2-minute route configurations, and the custom method is for convention-based Routing configuration, we use the default option for Attribute Routing: in "var controllerName = routeData. values ["controller"]. toString (); "add a judgment before the code: if (string. isNullOrWhiteSpace (routeData. route. routeTemplate) {return base. selectController (request);} The result is correct, and the solution may be considered again. You can provide any suggestions. However, either way, it is clear that for feature-based routing rules, the name of the Controller does not need to be included, in this case, we find the routing template on Acton to match the request URI, and then determine the corresponding Action.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.