ASP.NET http配置与route和querystring params映射

时间:2015-01-19 14:53:55

标签: c# asp.net asp.net-mvc asp.net-web-api routes

第一次发布海报,我有一个问题,对我而言,这感觉有点像101问题,但我一直无法让这些传统映射正确路由。目前,我有一个控制器(单独的c#库)和两个要映射的动作。

public class FindStuffController : ApiController
{
        [HttpGet()]
        public IEnumerable<StuffResource> FindStuffByDates(String emailAddress, DateTime start, DateTime end)
        {
            //do stuff...
        }

        [HttpGet()]
        public StuffResource FindStuffById(String emailAddress, String stuffId)
        {
            //do stuff...
        }
}

在WebApi项目的WebApiConfig中,我有以下映射:

public static void Register(HttpConfiguration config)
{
   GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;            GlobalConfiguration.Configuration.Formatters.Remove(config.Formatters.XmlFormatter);
     config.Filters.Add(new BasicTokenAuthorizationFilter());
     config.Filters.Add(new ExceptionHandlingFilter());

     config.Routes.MapHttpRoute(
                name: "FindStuffBetweenDates",
                routeTemplate: "stuff/{emailAddress}",
                defaults: new { controller = "FindStuff", action = "FindStuffByDates" }
            );

     config.Routes.MapHttpRoute(
                name: "FindStuffById",
                routeTemplate: "stuff/{emailAddress}/{stuffId}",
                defaults: new { controller = "FindStuff", action = "FindStuffById" }
            );
}

对于每个端点,出于向后兼容性原因,预期的uri应该是......
      “?〜/东西/ {EMAILADDRESS}开始= {开始}&安培;端= {结束}”
......和......       “〜/东西/ {EMAILADDRESS} / {stuffId}”

但是,我只能在测试中连接到“FindStuffById”。连接到“FindStuffBetweenDates”的任何和所有尝试都以404错误结束。作为注释,如果我更改映射以便所有操作参数都在路由或查询字符串中,则操作将被正确映射。这个问题似乎只是我在两者中都有参数。

最后我知道,允许在路由和查询字符串中都有动作参数,但现在我不能100%确定发生了什么。我甚至从动作中删除了DateTime参数并尝试将其路由而没有更多成功。我错过了一些明显的东西吗?

谢谢!

2 个答案:

答案 0 :(得分:0)

这应该可以正常工作。我猜测您的查询字符串格式不正确,或者您没有提供所有值(包括开始和结束)。 Web API要求所有参数都满足要匹配的操作。

所以实际网址应该是(对于字符串参数的情况)

/stuff/a@b?start=5&end=7

还考虑使用属性路由编写控制器代码,它将更清晰,更容易跟踪。这是一个例子

public class FindStuffController : ApiController
{
    [Route("stuff/{emailAddress}")]
    [HttpGet]
    public string FindStuffByDates(string emailAddress, string start, string end)
    {
        return "start = " + start + " end = " + end;
    }

    [Route("stuff/{emailAddress}/{stuffId}")]
    [HttpGet]
    public object FindStuffById(string emailAddress, string stuffId)
    {
        return "byId = " + stuffId;
    }
}

启动代码看起来像:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        // configure the rest of the services/formatters

        // Web API routes
        config.MapHttpAttributeRoutes();
    }
}

如果您希望参数是可选的,请在方法签名

中标记它们
    [Route("stuff/{emailAddress}")]
    [HttpGet]
    public string FindStuffByDates(string emailAddress, string start = null, string end = null)
    {
        return "start = " + start + " end = " + end;
    }

答案 1 :(得分:0)

对不起延迟,但我想我弄明白了什么。我认为IIS正在捕获路由,并将它们路由为路由,而不是http路由。

基本上,它认为一切都必须以“/”结束......

  ~/stuff/{emailAddress}?start={start}&end={end}

......是不可接受的但是......

 ~/stuff/{emailAddress}/?start={start}&end={end}

......工作得很好。

我加入了......

<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule"
           preCondition="" />

到项目web配置的system.webserver / modules部分,似乎已经解决了这个问题。可能不是最优雅的方式,但至少它是有效的。

然而,对于Yishai而言,我确实意识到这样的隐式映射是导致痛苦的原因。我是明确路由该方法的支持者。但是,我在计划中失去了这场辩论。