ASP.NET Web API中的可选查询字符串参数

我需要实现以下WebAPI方法:

/api/books?author=XXX&title=XXX&isbn=XXX&somethingelse=XXX&date=XXX 

所有查询字符串参数都可以为null。 也就是说,调用者可以指定从0到所有5个参数。

MVC4 beta中我曾经做过以下事情:

 public class BooksController : ApiController { // GET /api/books?author=tolk&title=lord&isbn=91&somethingelse=ABC&date=1970-01-01 public string GetFindBooks(string author, string title, string isbn, string somethingelse, DateTime? date) { // ... } } 

MVC4 RC不再像这样了。 如果我指定少于5个参数,它会回复404说:

未在与请求匹配的控制器“Books”上找到任何操作。

什么是正确的方法签名,使其行为像以前一样,而不必在URL路由中指定可选参数?

此问题已在MVC4的常规版本中得到修复。 现在你可以这样做:

 public string GetFindBooks(string author="", string title="", string isbn="", string somethingelse="", DateTime? date= null) { // ... } 

一切都将开箱即用。

如vijay建议的那样,可以将多个参数作为单个模型传递。 当您使用FromUri参数属性时,这适用于GET。 这告诉WebAPI从查询参数中填充模型。

结果是只有一个参数的清洁控制器动作。 有关详细信息,请参阅: http : //www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

 public class BooksController : ApiController { // GET /api/books?author=tolk&title=lord&isbn=91&somethingelse=ABC&date=1970-01-01 public string GetFindBooks([FromUri]BookQuery query) { // ... } } public class BookQuery { public string Author { get; set; } public string Title { get; set; } public string ISBN { get; set; } public string SomethingElse { get; set; } public DateTime? Date { get; set; } } 

它甚至支持多个参数,只要属性不冲突即可。

 // GET /api/books?author=tolk&title=lord&isbn=91&somethingelse=ABC&date=1970-01-01 public string GetFindBooks([FromUri]BookQuery query, [FromUri]Paging paging) { // ... } public class Paging { public string Sort { get; set; } public int Skip { get; set; } public int Take { get; set; } } 

更新
为了确保值是可选的,请确保对模型属性使用引用类型或nullables(例如int?)。

对所有参数使用初始默认值,如下所示

 public string GetFindBooks(string author="", string title="", string isbn="", string somethingelse="", DateTime? date= null) { // ... } 

如果要传递多个参数,则可以创建模型而不是传递多个参数。

如果你不想传递任何参数,那么你也可以跳过它,你的代码看起来整洁干净。

无法为未声明为“ optional ”的参数提供默认值

  Function GetFindBooks(id As Integer, ByVal pid As Integer, Optional sort As String = "DESC", Optional limit As Integer = 99) 

在您的WebApiConfig

  config.Routes.MapHttpRoute( _ name:="books", _ routeTemplate:="api/{controller}/{action}/{id}/{pid}/{sort}/{limit}", _ defaults:=New With {.id = RouteParameter.Optional, .pid = RouteParameter.Optional, .sort = UrlParameter.Optional, .limit = UrlParameter.Optional} _ )