C# 在URI中遇到尾随符号AND时,如何处理奇怪的行为?

C# 在URI中遇到尾随符号AND时,如何处理奇怪的行为?,c#,.net,asp.net-web-api,C#,.net,Asp.net Web Api,在向URI发送请求时,使用默认示例WebApi项目的稍加修改的版本,如下所示: 所有未指定的参数都以null形式显式传递给控制器,忽略任何默认值。这意味着对于这样的控制器功能: // GET api/values public IEnumerable<string> Get(bool all = true, string foo = "bar") { return all ? new [] {"value1", "value2", foo} : new [] {"value

在向URI发送请求时,使用默认示例WebApi项目的稍加修改的版本,如下所示:

所有未指定的参数都以null形式显式传递给控制器,忽略任何默认值。这意味着对于这样的控制器功能:

// GET api/values
public IEnumerable<string> Get(bool all = true, string foo = "bar")
{
    return all ? new [] {"value1", "value2", foo} : new [] {"value1", "value2"};
}
管道上的任何异常筛选器也会忽略此错误。移除尾随的符号,使其工作正常

一些Pentester认为这是一个安全风险,所以我需要以某种方式修复它。我不希望为了解决这个不太可能的问题,而需要遍历所有使用默认参数调用的控制器实例,并将它们更改为null

因此,如何执行以下操作之一:

  • 捕获此异常并用我自己的异常替换它
  • 完全拒绝这样的URI
  • 其他一些解决方案可以防止发生这种情况时类名显示在请求输出中(调试模式已关闭,但仍会执行此操作)

  • DelegatingHandler
    s在管道中调用控制器之前操作,并且可以捕获此错误

    此处理程序可用于检测此特定问题,并根据您的选择修复它,使默认模型绑定器再次正常工作,或引发异常并抱怨URI

    public class AmpersandHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            var uriString = request.RequestUri.OriginalString;
            if (uriString.Last() == '&')
            {
                request.RequestUri = new Uri(uriString.Substring(0, uriString.Length - 1));
                //return request.CreateErrorResponse(HttpStatusCode.BadRequest, "Unparseable URI - Trailing &");
            }
            return await base.SendAsync(request, cancellationToken);
        }
    }
    

    如果使用nullable呢<代码>布尔?all=true并在内部将“null”视为无效?是的,这是可行的,但我们的api解决方案中有数百个调用需要查看、更改和测试,所有这些都是因为当使用格式错误的URI时,默认值没有被正确使用。我正在寻找更全局的内容。您可以使用委派处理程序修复URI。您还可以使用操作筛选器检查响应,并在返回400时根据需要修改它。找到委派处理程序并使用它进行修复。好几年没涉足这段管道了,所以这可能有点明显,但好吧。我认为这可能是webapi框架中的一个bug,但是ModelBinder不应该这样做。
    public class AmpersandHandler : DelegatingHandler
    {
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
            CancellationToken cancellationToken)
        {
            var uriString = request.RequestUri.OriginalString;
            if (uriString.Last() == '&')
            {
                request.RequestUri = new Uri(uriString.Substring(0, uriString.Length - 1));
                //return request.CreateErrorResponse(HttpStatusCode.BadRequest, "Unparseable URI - Trailing &");
            }
            return await base.SendAsync(request, cancellationToken);
        }
    }
    
    config.MessageHandlers.Add(new AmpersandHandler());