【问题标题】:MVC Web API Routing to Wrong ActionMVC Web API 路由到错误的操作
【发布时间】: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 }
        );
    }

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

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

我在这里做错了什么?

【问题讨论】:

  • 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


【解决方案1】:

首先,日期中有一个类型。

这个2018-03-04:T12:30:00 应该是2018-03-04T12:30:00

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

这样试试

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

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

[ResponseType(typeof(ListReservationDTO))]
public IHttpActionResult GetReservationsByDate(DateTime StartDate, DateTime? EndDate)

注意DateTime?Nullable&lt;DateTime&gt; 的简写

【讨论】:

    猜你喜欢
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多