From 1c48261f4622b09188a75d55c94f8147dd00b6f8 Mon Sep 17 00:00:00 2001 From: Jark Reijerink Date: Tue, 4 Oct 2016 17:37:49 +0100 Subject: [PATCH] Added more validation around UriFormat to method mapping logic. Fixes #80. --- ...stRouteHandlerTests.UriFormatValidation.cs | 48 +++++++++++++++++++ .../Rest/RestControllerMethodInfo.cs | 17 +++++-- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/src/WebServer.UnitTests/Rest/RestRouteHandlerTests.UriFormatValidation.cs b/src/WebServer.UnitTests/Rest/RestRouteHandlerTests.UriFormatValidation.cs index cdce031..a56a47f 100644 --- a/src/WebServer.UnitTests/Rest/RestRouteHandlerTests.UriFormatValidation.cs +++ b/src/WebServer.UnitTests/Rest/RestRouteHandlerTests.UriFormatValidation.cs @@ -80,6 +80,54 @@ public async Task RegisterController_TwoDifferentControllersWithSimilarlyNamedMe await AssertHandleRequest("/Post", HttpMethod.POST, HttpResponseStatus.Created); } + private class UriFormatWitMisnamedPathInUrlController + { + [UriFormat("/Get/{param}/")] + public IGetResponse Get(string param2) => new GetResponse(GetResponse.ResponseStatus.OK, param2); + } + + [TestMethod] + public void RegisterController_AControllerWithMismatchedParametersInPath_ThrowsException() + { + AssertRegisterControllerThrows(); + } + + private class UriFormatWitMisnamedUriParameterInUrlController + { + [UriFormat("/Get/?param={param}")] + public IGetResponse Get(string param2) => new GetResponse(GetResponse.ResponseStatus.OK, param2); + } + + [TestMethod] + public void RegisterController_AControllerWithMismatchedParametersInUriParameters_ThrowsException() + { + AssertRegisterControllerThrows(); + } + + private class UriFormatWithMoreInUrlPathController + { + [UriFormat("/Get/{param}/{param2}")] + public IGetResponse Get(string param) => new GetResponse(GetResponse.ResponseStatus.OK, param); + } + + [TestMethod] + public void RegisterController_AControllerWithMoreInUrlPath_ThrowsException() + { + AssertRegisterControllerThrows(); + } + + private class UriFormatWithMoreInUrlParameterController + { + [UriFormat("/Get/?param={param}¶m2={param}")] + public IGetResponse Get(string param) => new GetResponse(GetResponse.ResponseStatus.OK, param); + } + + [TestMethod] + public void RegisterController_AControllerWithMoreInUrlParameter_ThrowsException() + { + AssertRegisterControllerThrows(); + } + private void AssertRegisterControllerThrows(params string[] args) where T : class { Assert.ThrowsException(() => diff --git a/src/WebServer/Rest/RestControllerMethodInfo.cs b/src/WebServer/Rest/RestControllerMethodInfo.cs index 5480243..de70092 100644 --- a/src/WebServer/Rest/RestControllerMethodInfo.cs +++ b/src/WebServer/Rest/RestControllerMethodInfo.cs @@ -112,16 +112,23 @@ private bool TryGetContentParameterType(MethodInfo methodInfo, out Type content) private ParameterValueGetter[] GetParameterGetters(MethodInfo methodInfo) { - var fromUriParams = (from p in methodInfo.GetParameters() - where p.GetCustomAttribute() == null - select p).ToList(); + var methodParameters = (from p in methodInfo.GetParameters() + where p.GetCustomAttribute() == null + select p).ToList(); - if (!ParametersHaveValidType(fromUriParams.Select(p => p.ParameterType))) + if (!ParametersHaveValidType(methodParameters.Select(p => p.ParameterType))) { throw new InvalidOperationException("Can't use method parameters with a custom type."); } - return fromUriParams.Select(x => GetParameterGetter(x, MatchUri)).ToArray(); + var parameterValueGetters = methodParameters.Select(x => GetParameterGetter(x, MatchUri)).ToArray(); + if (parameterValueGetters.Length != + MatchUri.Parameters.Count + MatchUri.PathParts.Count(x => x.PartType == PathPart.PathPartType.Argument)) + { + throw new Exception($"Uri format {MatchUri} has got more method parameters defined than the method has got."); + } + + return parameterValueGetters; } private static ParameterValueGetter GetParameterGetter(ParameterInfo parameterInfo, ParsedUri matchUri)