可选查询字符串参数。NET Web API

我需要实现以下WebAPI方法:

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

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

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

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路由中指定可选参数?

281327 次浏览

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

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

MVC4常规版本修复了此问题。 现在你可以做:

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} _
)

正如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; }
}
< p > 更新: < br > 为了确保值是可选的,请确保为models属性使用引用类型或空值(例如int?