【发布时间】:2018-09-17 18:58:24
【问题描述】:
我有一个 Web API 控制器,当我调用默认的 Get 操作时,这有效,当我调用另一个特定操作 (GetReservationsForCustomer) 时,这也有效,但是一个操作给出错误 (GetReservationsByDate),它似乎路由到默认值采取行动。代码如下:
// GET: api/Reservations
public IQueryable<Reservation> GetReservations()
{
return db.Reservations;
}
[ResponseType(typeof(ReservationDTO))]
public IHttpActionResult GetReservationsForCustomer(int CustomerId)
{
IEnumerable<Reservation> reservations = db.Reservations.Where(r => r.CustomerId == CustomerId).ToList();
List<ReservationDTO> reservationList = new List<ReservationDTO>();
foreach(Reservation reservation in reservations)
{
reservationList.Add(new ReservationDTO
{
id = reservation.id,
ReservationStart = reservation.ReservationStart,
Covers = reservation.Covers
});
}
return Ok(reservationList);
}
[ResponseType(typeof(ListReservationDTO))]
public IHttpActionResult GetReservationsByDate(DateTime StartDate, DateTime EndDate)
{
IEnumerable<Reservation> reservations = new List<Reservation>();
if (EndDate != null)
{
reservations = db.Reservations.Where(r => r.ReservationStart.Date >= StartDate.Date && r.ReservationStart.Date >= EndDate.Date).ToList();
}
else
{
reservations = db.Reservations.Where(r => r.ReservationStart.Date == StartDate.Date).ToList();
}
List<ReservationDTO> reservationList = new List<ReservationDTO>();
foreach (Reservation res in reservations)
{
reservationList.Add(new ReservationDTO
{
id = res.id,
ReservationStart = res.ReservationStart,
Covers = res.Covers,
CustomerEmail = res.Customer.EmailAddress,
CustomerName = res.Customer.Name,
CustomerPhone = res.Customer.PhoneNumber
});
}
return Ok(reservationList);
}
这是我的 API 调用:
http://localhost:55601/api/Reservations/GetReservationsByDate/?StartDate=2018-03-04:T12:30:00
下面是回复:
{
"Message": "The request is invalid.",
"MessageDetail": "The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Web.Http.IHttpActionResult GetReservation(Int32)' in 'GreenLionBookings.API.ReservationsController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter."
}
请注意,该操作的具体细节在此阶段不相关,我已经尽力让它发挥作用!我试过指定开始日期和结束日期,但似乎都不起作用。它似乎总是被路由到默认的 Get 操作。
这是我的 RouteConfig:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
这是我的 WebApiConfig:
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
所以两者基本上都是默认的。
为什么这没有路由到正确的操作,只针对这个而不是其他?我有另一个控制器(客户),它似乎也适用于所有操作。我读过this 和this,还有this 和this,实际上我认为它们非常相关且很有帮助,但并没有解决我的问题。
我在这里做错了什么?
【问题讨论】:
-
endDate是必填参数,没有默认值。因此,该操作不是匹配路由的候选者,而是选择了默认路由。随后失败,因为id没有价值。 -
你应该省略 url 的动作名称,让框架将请求与参数名称匹配,试试这样localhost:55601/api/Reservations?StartDate=2018-03-04:T12:30:00
-
看起来你在日期中有一个 typeo,2018-03-04:T12:30:00 应该是 2018-03-04T12:30:00
-
@MattG Np,我应该把这个作为答案发布吗?
-
@MarcusHöglund 是的,请,我将标记为已接受。干杯
标签: asp.net-web-api