如何发送以句点字符结尾的查询字符串?

How to send a query string that ends in a period character?

我有一个 Web API 项目,具有以下端点:

GET api/search/{searchValue}

控制器代码:

[RoutePrefix("api/Search")]
public class SearchController : ApiController
{
    [HttpGet]
    [Route("{searchValue}", Name = "GenericSearch")]
    [ResponseType(typeof(SearchResponse))]
    public async Task<IHttpActionResult> Search(string searchValue) {
        ...
    }
}

这适用于大多数搜索字符串。但是,如果搜索字符串以句点 (.) 字符结尾,请求将以 404 中断;它似乎将句点解释为路径的一部分而不是查询的一部分。就是这样,即使请求字符串是 Url 编码的,例如

api/search/foo%2E

如果句点不是字符串的最后一个字符,则有效:

api/search/foo%2Ebar

将正确搜索 "foo.bar"。

如何解决此问题,以便允许用户搜索以句点字符结尾的字符串?

更新: 在将这个问题作为 this question 的副本关闭后,请允许我澄清为什么这个问题不同:

  1. 链接的问题试图在查询字符串中使用文字句点字符。我什至没有那样做;我将 . 编码为 %2E,它 仍然 不工作。
  2. 查询使用中间的句点字符。只有当它在查询字符串的末尾时才会失败。
  3. 我已经有 <modules runAllManagedModulesForAllRequests="true" />(正如我 web.configaccepted answer 所建议的那样)。
  4. 我尝试按照 highest-voted answer 中的建议在查询后添加斜杠字符(即 api\search\foo%2E\);这没什么区别。
  5. 我尝试了那里建议的所有答案,其中 none 个有所作为。

更新:

我没有提到以下内容也已添加到我的 Web 配置文件中,以允许句点不会导致 IIS 中断。

<system.web>
    <httpRuntime targetFramework="4.5" sendCacheControlHeader="true" relaxedUrlToFileSystemMapping="true" />
    <!-- ...other code removed for brevity -->
</system.web>

主要relaxedUrlToFileSystemMapping="true"表示HTTP请求中的URL是否需要是有效的Windows文件路径。

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.


原创

使用路由模板中的 catch all 参数 {*searchValue} 我能够让控制器操作与预期的路由前缀 api/search 和 return 匹配请求。即使对于以句点 (.) 结尾的值,无论 URL 是否编码。

[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) {
        //...
    }
}