一个控制器中的多个路由会导致 400:错误请求

multiple routes in one controller causes 400:bad request

本文关键字:请求 错误 路由 一个 控制器      更新时间:2023-09-26

让我举个我的问题的例子,我已经注册了我的路由如下(路由配置.cs):

routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

如果你看看我的控制器,它具有以下功能;

[Route("all")]
public HttpResponseMessage Get(HttpRequestMessage request)
{
    return CreateHttpResponse(request, () =>
    {
        HttpResponseMessage response = null;
        var HolidayCalendars = _holidayCalendarsRepository.GetAll().ToList();
        IEnumerable<HolidayCalendarViewModel> holiVm = Mapper.Map<IEnumerable<HolidayCalendar>, IEnumerable<HolidayCalendarViewModel>>(HolidayCalendars);
        response = request.CreateResponse<IEnumerable<HolidayCalendarViewModel>>(HttpStatusCode.OK, holiVm);
        return response;
    });
}

到目前为止,一切都进展顺利。我的页面加载了请求的数据。现在,例如,当我去添加另一个函数时;

[Route("allHolidays/{id:int}")]
public HttpResponseMessage GetHolidays(HttpRequestMessage request, int id)
{
    return CreateHttpResponse(request, () =>
    {
        HttpResponseMessage response = null;
        HolidayCalendar Calendar = _holidayCalendarsRepository.GetSingle(id);
        var Holidays = Calendar.Holidays.OrderBy(s => s.HolidayDate).ToList();
        IEnumerable<HolidayViewModel> holidayVm = Mapper.Map<IEnumerable<Holiday>, IEnumerable<HolidayViewModel>>(Holidays);
        response = request.CreateResponse<IEnumerable<HolidayViewModel>>(HttpStatusCode.OK, holidayVm);
        return response;
    });
}

我会在我的网页上收到以下错误;

无法加载资源:服务器响应状态为 400(错误请求)

奇怪的是,我的请求没有改变,我的 API 中只有一个新的控制器。

例如,这不应该发生,因为我的代码正在请求不同的路由;

function loadData() {
    apiService.get('/api/HolidayCalendars/all', null,
                HolidayCalendarLoadCompleted,
                HolidayCalendarLoadFailed);
}

function loadData() {
    apiService.get('/api/HolidayCalendars/allHolidays?id=' + $routeParams.id, null,
                HolidaysLoadCompleted,
                HolidaysLoadFailed);
}

有什么想法吗?

构造函数类 WebApiConfig:

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();
    config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new {id = RouteParameter.Optional }
    );
}

您的allHolidays路线暗示了这种格式

/api/HolidayCalendars/allHolidays/123

根据您的路线属性

[Route("allHolidays/{id:int}")]

但您已将 id 作为查询字符串参数传递

api/HolidayCalendars/allHolidays?id=123

看起来你在控制器上使用属性路由 (http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2):

[Route("all")]

但您在配置中使用标准路由:

routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );

尝试使用以下命令激活属性路由:

configuration.MapHttpAttributeRoutes();

其中配置是 HttpConfiguration 的实际实例。

问题出在您的 WebApiConfig 中。在路由模板中,尚未指定操作。

routeTemplate: "api/{controller}/{id}",

如果我没记错的话,这是 WebAPI 的默认配置。它按谓词筛选控制器上的请求。这就是为什么当你打电话

apiService.get('/api/HolidayCalendars/all'.....)

它返回 HolidayCalendars 控制器上的 Get() 方法。

若要解决此问题,请将 {action} 参数添加到路由模板:

public static void Register(HttpConfiguration config)
    {
config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new {id = RouteParameter.Optional }
            );
}

我终于找到了解决方案!

在我的代码顶部,我引用了System.Web.Mvc。这样,路由和 RESTful 函数就不会像在 Web API 中那样被解释。这导致我的应用程序中出现了一些奇怪的功能。

溶液:

改变

using System.Web.Mvc;

using System.Web.Http;

这让我躲避了三天,直到我得出了以下答案:https://stackoverflow.com/a/21999235/6033193