【问题标题】:.NET WebApi breaks when url ends with ampersand当 url 以 & 符号结尾时,.NET WebApi 中断
【发布时间】:2018-04-04 00:42:21
【问题描述】:

我有一个 ApiController - 例如“Home”控制器,带有动作“Test”,它接受两个参数 - test1 和 test2,两者都具有默认值

[System.Web.Http.HttpGet]
public ActionResult Test(int test1 = 3, int test2 = 5)
{
    var a = 0;
    return null;
}

现在当我调用 Home/Test?test1=1 时,一切正常。
但是当我调用 Home/Test?test1=1& 时,服务器会抛出异常

参数字典包含方法的不可为空类型“System.Int32”的参数“test2”的空条目 'System.Web.Mvc.ActionResult 测试(Int32,Int32)' 在 'TestAPI.Controllers.ValuesController'。可选参数必须是 引用类型、可为空的类型或被声明为可选项 参数。

我的路由配置目前是这样的:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
    );
}

这也发生在一个全新的 WebApi 项目上,所以它不是我的配置。
最大的问题是这个 & 符号来自一个客户项目,我不能在那里更改它,尽管我知道这是一个错误的请求。

最奇怪的是,如果 Home 控制器继承的是 Controller 而不是 ApiController - 一切都很好。

编辑 1
我忘了提到,如果我将参数设为可为空(即 int?),那么错误就会消失,但 test2 在调用错误 URL 时的值为 null 而不是 5,所以这不是我的选择。

【问题讨论】:

  • 您刚刚告诉服务器您有另一个参数(这就是 & 的意思),但 没有 提供任何参数。破坏的不是 Web API。错误消息清楚地解释了如何解决这个问题 - 使用可为空的参数。将类型更改为int?
  • 使用int? 一个选项。只需在您的代码中使用test2??5,例如var actualTest2 = test2 ?? 5;
  • & 结尾的 URI 是否符合规范?
  • 我知道当服务器需要一个参数时我不提供参数,但是当使用 MVC 控制器时服务器理解请求。我在应用程序中有很多操作,我不想开始检查每个参数的正确值。
  • @Amy 是的,它是有效的。

标签: c# url asp.net-web-api2


【解决方案1】:

您可以使用自定义 DelegatingHandler 并删除尾随的“&”:

public class SanitizeHandler : System.Net.Http.DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.RequestUri.ToString().EndsWith("&"))
            request.RequestUri = new Uri(request.RequestUri.ToString().TrimEnd('&'));

        return base.SendAsync(request, cancellationToken);
    }
}

Application_Start注册新的Handler:

GlobalConfiguration.Configuration.MessageHandlers.Add(new SanitizeHandler());

或者将它添加到你的HttpConfiguration(然后它只被Webapi调用调用):

public static void Register(HttpConfiguration config)
{
    ...
    config.MessageHandlers.Add(new SanitizeHandler());
    ...   
}

【讨论】:

  • 或类似含义的Owin中间件(如果是基于Owin的Web Api)。
  • 我希望有一些更简单的东西,但这也可以。谢谢!
猜你喜欢
  • 2016-08-05
  • 1970-01-01
  • 2012-11-04
  • 2019-01-24
  • 2018-10-23
  • 1970-01-01
  • 2015-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多