ASP.NET Web API中的可选参数
我需要实现以下WebAPI方法:
/api/books?author=XXX&title=XXX&isbn=XXX&somethingelse=XXX&date=XXX
所有参数都可以为null,即调用者可以从0指定所有5个参数。
在MVC4testing版中,我曾经做过以下操作:
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的行为不再这样了。 如果我指定less于5个参数,它回答404
说
没有find符合请求的控制器“书籍”的操作。
什么是正确的方法签名,使其行为就像以前一样,而不必在URL路由中指定可选参数?
这个问题已经在MVC4的定期发布中得到解决。 现在你可以做:
public string GetFindBooks(string author="", string title="", string isbn="", string somethingelse="", DateTime? date= null) { // ... }
所有的东西都可以在盒子里运行
像维杰build议的那样,可以将多个参数作为单个模型传递。 这适用于使用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; } }
更新 :
为了确保值是可选的,请确保为模型属性使用引用types或可空(例如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} _ )
如果你想传递多个参数,那么你可以创build模型,而不是传递多个参数。
如果你不想传递任何参数,那么你可以跳过它,你的代码将看起来整洁干净。