MVC Web API路由到错误的操作

时间:2018-04-08 06:05:38

标签: asp.net-web-api

我有一个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 }
        );
    }

所以两者基本上都是默认的。

为什么这不是路由到正确的操作,只是为了这个而不是其他的?我有另一个控制器(客户)似乎也适用于所有操作。我读过thisthis,还有thisthis,我认为这些内容非常相关且非常有用,但并没有解决我的问题。

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

首先,你在日期中有一个版型。

Function maxIfs(maxRange As Range, criteriaRange As Range, criterion As \Variant) As Variant maxIfs = Empty For i = 1 To maxRange.Cells.count If Left(criteriaRange.Cells(i).text, findN(criteriaRange.Cells(i).value)) = Criteria.value Then If maxIfs = Empty Then maxIfs = maxRange.Cells(i).value Else maxIfs = Application.WorksheetFunction.Max(maxIfs, maxRange.Cells(i).value) End If End If Next End Function Function findN(text As Variant) As Integer 'Gives the position of the nth delimiter Dim found As Integer Dim place As Integer found = 0 place = 0 For i = 1 To Len(text) + 1 ' Add 1 as we start at 1 not zero place = found 'this will be 0 the first time round found = InStr(found + 1, text, ".") Next i findN = place End Function 应为2018-03-04:T12:30:00

然后,为了解决路由问题,您可以省略url的动作名称,让框架根据参数名称匹配请求。

尝试这样

2018-03-04T12:30:00

然后,如果您希望能够将可空值发送到EndDate,这是DateTime的值类型;使DateTime可以为空

api/Reservations?StartDate=2018-03-04T12:30:00&EndDate=2018-03-05T12:30:00 

请注意[ResponseType(typeof(ListReservationDTO))] public IHttpActionResult GetReservationsByDate(DateTime StartDate, DateTime? EndDate) ,它是DateTime?

的简写