diff --git a/Unosquare.Labs.EmbedIO.Tests/TestObjects/TestController.cs b/Unosquare.Labs.EmbedIO.Tests/TestObjects/TestController.cs index 7c42b1e57..367ed873f 100644 --- a/Unosquare.Labs.EmbedIO.Tests/TestObjects/TestController.cs +++ b/Unosquare.Labs.EmbedIO.Tests/TestObjects/TestController.cs @@ -21,6 +21,7 @@ public class Person public const string RelativePath = "api/"; public const string GetPath = RelativePath + "people/"; + public const string GetMiddlePath = RelativePath + "person/*/select"; public static List People = new List { @@ -29,6 +30,31 @@ public class Person new Person() {Key = 3, Name = "Luis Gonzalez", Age = 29, EmailAddress = "luis.gonzalez@unosquare.com"}, }; + [WebApiHandler(HttpVerbs.Get, "/" + GetMiddlePath)] + public bool GetPerson(WebServer server, HttpListenerContext context) + { + try + { + // read the middle segment + var segment = context.Request.Url.Segments.Reverse().Skip(1).First().Replace("/", ""); + + // otherwise, we need to parse the key and respond with the entity accordingly + int key; + + if (int.TryParse(segment, out key) && People.Any(p => p.Key == key)) + { + return context.JsonResponse(People.FirstOrDefault(p => p.Key == key)); + } + + throw new KeyNotFoundException("Key Not Found: " + segment); + } + catch (Exception ex) + { + context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; + return context.JsonResponse(ex); + } + } + [WebApiHandler(HttpVerbs.Get, "/" + GetPath + "*")] public bool GetPeople(WebServer server, HttpListenerContext context) { diff --git a/Unosquare.Labs.EmbedIO.Tests/WebApiModuleTest.cs b/Unosquare.Labs.EmbedIO.Tests/WebApiModuleTest.cs index 19e686f2f..ca7991e8d 100644 --- a/Unosquare.Labs.EmbedIO.Tests/WebApiModuleTest.cs +++ b/Unosquare.Labs.EmbedIO.Tests/WebApiModuleTest.cs @@ -75,6 +75,31 @@ public void GetJsonData() } } + [Test] + public void GetJsonDataWithMiddleUrl() + { + var person = TestController.People.First(); + + var singleRequest = + (HttpWebRequest) + WebRequest.Create(Resources.ServerAddress + TestController.GetMiddlePath.Replace("*", person.Key.ToString())); + + using (var response = (HttpWebResponse) singleRequest.GetResponse()) + { + Assert.AreEqual(response.StatusCode, HttpStatusCode.OK, "Status Code OK"); + + var jsonBody = new StreamReader(response.GetResponseStream()).ReadToEnd(); + + Assert.IsNotNullOrEmpty(jsonBody, "Json Body is not null or empty"); + + var item = JsonConvert.DeserializeObject(jsonBody); + + Assert.IsNotNull(item, "Json Object is not null"); + Assert.AreEqual(item.Name, person.Name, "Remote objects equality"); + Assert.AreEqual(item.Name, TestController.People.First().Name, "Remote and local objects equality"); + } + } + [Test] public void PostJsonData() { diff --git a/Unosquare.Labs.EmbedIO/Modules/WebApiModule.cs b/Unosquare.Labs.EmbedIO/Modules/WebApiModule.cs index 8634a0bfb..433942b2f 100644 --- a/Unosquare.Labs.EmbedIO/Modules/WebApiModule.cs +++ b/Unosquare.Labs.EmbedIO/Modules/WebApiModule.cs @@ -32,11 +32,16 @@ public WebApiModule() var path = context.RequestPath(); var verb = context.RequestVerb(); var wildcardPaths = DelegateMap.Keys - .Where(k => k.EndsWith("/" + ModuleMap.AnyPath)) + .Where(k => k.Contains("/" + ModuleMap.AnyPath)) .Select(s => s.ToLowerInvariant()) .ToArray(); - var wildcardMatch = wildcardPaths.FirstOrDefault(p => path.StartsWith(p.Substring(0, p.Length - 1))); + var wildcardMatch = wildcardPaths.FirstOrDefault(p => // wildcard at the end + path.StartsWith(p.Substring(0, p.Length - ModuleMap.AnyPath.Length)) + // wildcard in the middle so check both start/end + || (path.StartsWith(p.Substring(0, p.IndexOf(ModuleMap.AnyPath, StringComparison.Ordinal))) + && path.EndsWith(p.Substring(p.IndexOf(ModuleMap.AnyPath, StringComparison.Ordinal) + 1))) + ); if (string.IsNullOrWhiteSpace(wildcardMatch) == false) path = wildcardMatch; @@ -59,15 +64,15 @@ public WebApiModule() var methodPair = DelegateMap[path][verb]; var controller = methodPair.Item1(); - if (methodPair.Item2.ReturnType == typeof(Task)) + if (methodPair.Item2.ReturnType == typeof (Task)) { - var method = Delegate.CreateDelegate(typeof(AsyncResponseHandler), controller, methodPair.Item2); + var method = Delegate.CreateDelegate(typeof (AsyncResponseHandler), controller, methodPair.Item2); server.Log.DebugFormat("Handler: {0}.{1}", method.Method.DeclaringType.FullName, method.Method.Name); context.NoCache(); var returnValue = Task.Run(async () => { - var task = await (Task)method.DynamicInvoke(server, context); + var task = await (Task) method.DynamicInvoke(server, context); return task; }); @@ -75,11 +80,11 @@ public WebApiModule() } else { - var method = Delegate.CreateDelegate(typeof(ResponseHandler), controller, methodPair.Item2); + var method = Delegate.CreateDelegate(typeof (ResponseHandler), controller, methodPair.Item2); server.Log.DebugFormat("Handler: {0}.{1}", method.Method.DeclaringType.FullName, method.Method.Name); context.NoCache(); - var returnValue = (bool)method.DynamicInvoke(server, context); + var returnValue = (bool) method.DynamicInvoke(server, context); return returnValue; } });