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