Advertisement
Guest User

Untitled

a guest
Feb 24th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.69 KB | None | 0 0
  1. <pre>
  2.  
  3. namespace WebAPiVersioningHybrid.Routing
  4. {
  5. // This version for custome attribute routing
  6. public class NamespaceHttpControllerSelector : IHttpControllerSelector
  7. {
  8. private readonly HttpConfiguration _configuration;
  9. private readonly Lazy<Dictionary<string, HttpControllerDescriptor>> _controllers;
  10. public NamespaceHttpControllerSelector(HttpConfiguration config)
  11. {
  12. _configuration = config;
  13. _controllers = new Lazy<Dictionary<string, HttpControllerDescriptor>>(InitializeControllerDictionary);
  14. }
  15. public HttpControllerDescriptor SelectController(HttpRequestMessage request)
  16. {
  17. var routeData = request.GetRouteData();
  18. if (routeData == null)
  19. {
  20. throw new HttpResponseException(HttpStatusCode.NotFound);
  21. }
  22. var controllerName = GetControllerName(routeData);
  23. if (controllerName == null)
  24. {
  25. throw new HttpResponseException(HttpStatusCode.NotFound);
  26. }
  27. var namespaceName = GetVersion(routeData);
  28. if (namespaceName == null)
  29. {
  30. throw new HttpResponseException(HttpStatusCode.NotFound);
  31. }
  32. var controllerKey = String.Format(CultureInfo.InvariantCulture, "{0}.{1}",
  33. namespaceName, controllerName);
  34.  
  35. HttpControllerDescriptor controllerDescriptor;
  36. if (_controllers.Value.TryGetValue(controllerKey, out controllerDescriptor))
  37. {
  38. return controllerDescriptor;
  39. }
  40. throw new HttpResponseException(HttpStatusCode.NotFound);
  41. }
  42. public IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
  43. {
  44. return _controllers.Value;
  45. }
  46. private Dictionary<string, HttpControllerDescriptor> InitializeControllerDictionary()
  47. {
  48. var dictionary = new Dictionary<string, HttpControllerDescriptor>(StringComparer.OrdinalIgnoreCase);
  49. var assembliesResolver = _configuration.Services.GetAssembliesResolver();
  50. var controllersResolver = _configuration.Services.GetHttpControllerTypeResolver();
  51. var controllerTypes = controllersResolver.GetControllerTypes(assembliesResolver);
  52. foreach (var controllerType in controllerTypes)
  53. {
  54. var segments = controllerType.Namespace.Split(Type.Delimiter);
  55. var controllerName = controllerType.Name.Remove(controllerType.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length);
  56. var controllerKey = String.Format(CultureInfo.InvariantCulture, "{0}.{1}",
  57. segments[segments.Length - 1], controllerName);
  58. if (!dictionary.Keys.Contains(controllerKey))
  59. {
  60. dictionary[controllerKey] = new HttpControllerDescriptor(_configuration,
  61. controllerType.Name,
  62. controllerType);
  63. }
  64. }
  65. return dictionary;
  66. }
  67. private static T GetRouteVariable<T>(IHttpRouteData routeData, IEnumerable<string> names)
  68. {
  69. object result;
  70.  
  71. foreach (var name in names)
  72. {
  73. if (routeData.Values.TryGetValue(name, out result))
  74. {
  75. return (T)result;
  76. }
  77. }
  78. return default(T);
  79. }
  80.  
  81. private string GetControllerName(IHttpRouteData routeData)
  82. {
  83. var subroute = routeData.GetSubRoutes().FirstOrDefault();
  84. if (subroute == null) return null;
  85.  
  86. //var dataTokenValue = subroute.Route.DataTokens.Last().Value;
  87. var dataTokenValue = subroute.Route.DataTokens.First().Value;
  88.  
  89. if (dataTokenValue == null) return null;
  90. var controllername = ((HttpActionDescriptor[])dataTokenValue).First().ControllerDescriptor.ControllerName.Replace("Controller", string.Empty);
  91. return controllername;
  92. }
  93.  
  94. private string GetVersion(IHttpRouteData routeData)
  95. {
  96. var subRouteData = routeData.GetSubRoutes().FirstOrDefault();
  97. if (subRouteData == null) return null;
  98. var routevariable = GetRouteVariable<string>(subRouteData, versionnumber);
  99. return routevariable;
  100. }
  101.  
  102. private List<string> versionnumber = new List<string>()
  103. {
  104. "apiVersion1" ,
  105. "apiVersion2"
  106. };
  107. }
  108. }
  109. </pre>
  110.  
  111. Each control are decorated by custom route attribute , that defines the version of current control and helps the NamespaceHttpControllerSelector.cs to return the correct descriptor
  112.  
  113. <pre>
  114. <code>
  115. namespace WebAPiVersioningHybrid.Routing
  116. {
  117. public class ApiVersion1Constraint : IHttpRouteConstraint
  118. {
  119. public ApiVersion1Constraint(string allowedVersion)
  120. {
  121. AllowedVersion = allowedVersion.ToLowerInvariant();
  122. }
  123. public string AllowedVersion { get; private set; }
  124. //Matching the version from requested route
  125. public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName,
  126. IDictionary<string, object> values, HttpRouteDirection routeDirection)
  127. {
  128. object value;
  129. if (values.TryGetValue(parameterName, out value) && value != null)
  130. {
  131. return AllowedVersion.Equals(value.ToString().ToLowerInvariant());
  132. }
  133. return false;
  134. }
  135. }
  136.  
  137. }
  138.  
  139. using System;
  140. using System.Collections.Generic;
  141. using System.Linq;
  142. using System.Net.Http;
  143. using System.Web;
  144. using System.Web.Http.Routing;
  145.  
  146. namespace WebAPiVersioningHybrid.Routing
  147. {
  148. public class ApiVersion2Constraint : IHttpRouteConstraint
  149. {
  150. public ApiVersion2Constraint(string allowedVersion)
  151. {
  152. AllowedVersion2 = allowedVersion.ToLowerInvariant();
  153. }
  154. public string AllowedVersion2 { get; private set; }
  155. //Matching the version from requested route
  156. public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName,
  157. IDictionary<string, object> values, HttpRouteDirection routeDirection)
  158. {
  159. object value;
  160. if (values.TryGetValue(parameterName, out value) && value != null)
  161. {
  162. return AllowedVersion2.Equals(value.ToString().ToLowerInvariant());
  163. }
  164. return false;
  165. }
  166. }
  167. }
  168. </code>
  169. </pre>
  170.  
  171. The Web API that used custom namespace versioning are working fine that are listed below
  172.  
  173. <pre>
  174. <code>
  175. using WebAPiVersioningHybrid.Models;
  176.  
  177. namespace WebAPiVersioningHybrid.Controllers.V1
  178. {
  179. [RoutePrefix("api/{apiVersion1:apiVersion1Constraint(v1)}/Teacher")]
  180. public class TeacherController : ApiController
  181. {
  182. // http://localhost/WebAPiVersioningHybrid/api/V1/Teacher/GetTeacher
  183.  
  184. [Route("GetTeacher")]
  185. public HttpResponseMessage GetValue()
  186. {
  187. return Request.CreateResponse(HttpStatusCode.Accepted, new Teacher(1, "Dale", "Carn", 40));
  188. }
  189. }
  190. }
  191.  
  192. using WebAPiVersioningHybrid.Models;
  193.  
  194. namespace WebAPiVersioningHybrid.Controllers.V2
  195. {
  196. [RoutePrefix("api/{apiVersion2:apiVersion2Constraint(v2)}/Teacher")]
  197. public class TeacherController : ApiController
  198. {
  199. [Route("GetTeacher")]
  200. public HttpResponseMessage GetValue()
  201. {
  202. return Request.CreateResponse(HttpStatusCode.Accepted,
  203. new TeacherDetails(1,"Dan","Carn",40,"XY@gmail.com","009827788","XYZ","20"));
  204. }
  205. }
  206. }
  207. </code>
  208. </pre>
  209. The old Web API thaht are used conventional , that is not working with the conventional routing any more and can not be modified for namespace versioning web api for backward purposes
  210.  
  211. <pre>
  212. <code>
  213. using System.Net;
  214. using System.Net.Http;
  215. using System.Web.Http;
  216. using WebAPiVersioningHybrid.Models;
  217.  
  218. namespace WebAPiVersioningHybrid.Controllers
  219. {
  220. // http://localhost/WebAPiVersioningHybrid/api/Person
  221. public class PersonController : ApiController
  222. {
  223. public HttpResponseMessage GetPerson()
  224. {
  225. return Request.CreateResponse(HttpStatusCode.Accepted,new Person("782901865","Male"));
  226. }
  227. }
  228. }
  229.  
  230. </code>
  231. </pre>
  232.  
  233. The follwoing classes at Model folder
  234. <pre>
  235. <code>
  236. namespace WebAPiVersioningHybrid.Models
  237. {
  238. public class Person
  239. {
  240. public string SSN { get; set; }
  241. public string Gender { get; set; }
  242. public Person(string SSN,string Gender)
  243. {
  244. this.Gender =Gender;
  245. this.SSN = SSN;
  246. }
  247. }
  248. }
  249.  
  250. namespace WebAPiVersioningHybrid.Models
  251. {
  252. public class Teacher
  253. {
  254. public int Id { get; set; }
  255. public string FirstName { get; set; }
  256. public string LastName { get; set; }
  257. public int Age { get; set; }
  258.  
  259. public Teacher(int Id,string FirstName,string LastName,int Age)
  260. {
  261. this.Id = Id;
  262. this.FirstName = FirstName;
  263. this.LastName = LastName;
  264. this.Age = Age;
  265. }
  266. }
  267. }
  268.  
  269. namespace WebAPiVersioningHybrid.Models
  270. {
  271. public class TeacherDetails: Teacher
  272. {
  273. public string email { get; set; }
  274. public string MobileNum { get; set; }
  275. public string Street { get; set; }
  276. public string BuildingNum { get; set; }
  277. public TeacherDetails(int Id,string FirstName,string LastName,int Age,
  278. string email,string MobileNum,string Street,string BuildingNum)
  279. :base(Id,FirstName,LastName,Age)
  280. {
  281. this.email = email;
  282. this.MobileNum = MobileNum;
  283. this.Street = Street;
  284. this.BuildingNum = BuildingNum;
  285. }
  286. }
  287. }
  288. </pre>
  289. <pre>
  290. <code>
  291. namespace WebAPiVersioningHybrid
  292. {
  293. public static class WebApiConfig
  294. {
  295. public static void Register(HttpConfiguration config)
  296. {
  297. // Web API configuration and services
  298.  
  299. // Web API routes
  300. var constraintsResolver = new DefaultInlineConstraintResolver();
  301. constraintsResolver.ConstraintMap.Add("apiVersion1Constraint", typeof(ApiVersion1Constraint));
  302. constraintsResolver.ConstraintMap.Add("apiVersion2Constraint", typeof(ApiVersion2Constraint));
  303. config.MapHttpAttributeRoutes(constraintsResolver);
  304. // this work in conventional routing
  305. // config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config));
  306. config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config));
  307.  
  308.  
  309. config.Routes.MapHttpRoute(
  310. name: "DefaultApi",
  311. routeTemplate: "api/{controller}/{id}",
  312. defaults: new { id = RouteParameter.Optional }
  313. );
  314. }
  315. }
  316. }
  317. <code>
  318. </pre>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement