I have a web API project, with the following endpoint:
GET api/search/{searchValue}
Controller code:
[RoutePrefix("api/Search")]
public class SearchController : ApiController
{
[HttpGet]
[Route("{searchValue}", Name = "GenericSearch")]
[ResponseType(typeof(SearchResponse))]
public async Task<IHttpActionResult> Search(string searchValue) {
...
}
}
This works fine for most search strings. But if the search string ends in a period (.
) character, the request breaks with a 404; it seems to be interpreting the period as part of the path rather than as part of the query. This is so, even if the request string is Url encoded, e.g.
api/search/foo%2E
If the period is not the last character of the string, it works:
api/search/foo%2Ebar
will correctly search for "foo.bar".
How can I fix this so that users are allowed to search for strings that end with a period character?
UPDATE: After having this question closed as a duplicate of this question, allow me to clarify why this question is different:
.
as %2E
, and it's still not working.<modules runAllManagedModulesForAllRequests="true" />
(as suggested by the accepted answer in my web.config
.api\search\foo%2E\
) as suggested in the highest-voted answer; this made no difference.UPDATE:
I failed to mention that the following was also added to my web config file to allow the period to not cause IIS to break.
<system.web>
<httpRuntime targetFramework="4.5" sendCacheControlHeader="true" relaxedUrlToFileSystemMapping="true" />
<!-- ...other code removed for brevity -->
</system.web>
Primarily relaxedUrlToFileSystemMapping="true"
that indicates whether the URL in an HTTP request is required to be a valid Windows file path.
HttpRuntimeSection.RelaxedUrlToFileSystemMapping Property
The RelaxedUrlToFileSystemMapping property determines how the URL in an incoming HTTP request will be validated. If this property is false, the URL is validated by using the same rules that determine whether a Windows file system path is valid.
ORIGINAL
Using the catch all parameter in the route template {*searchValue}
I was able to get the controller action to match the request with route prefix api/search
and return as expected. Even for values ending with a period (.
), whether URL encoded or not.
[RoutePrefix("api/search")]
public class SearchController : ApiController {
[HttpGet]
[Route("{*searchValue}", Name = "GenericSearch")] // Matches GET api/Seach/{anything here}
[ResponseType(typeof(SearchResponse))]
public async Task<IHttpActionResult> Search(string searchValue) {
//...
}
}