简体   繁体   中英

Web api routing - cannot access default route?

I would like the following routes in my web api:

/api/week/2013/08/29 <-- this is a specific week

/api/week/ <-- this is the last week

{and some default route to other api-controllers}

I've implemented a Get function which correctly retrieves the information, but I have a problem with the routing.

I have declared the following:

   config.Routes.MapHttpRoute(
         name: "WeekRoute",
         routeTemplate: "api/week/{year}/{month}/{day}",
         defaults: new { controller = "Week" },
         constraints: new { year = @"\d{1,4}", month = @"[1-9]|1[0-2]", day = @"[0-9]|[0-2][0-9]|3[0-1]" }
    );

    // I don't think I'd even need this one, but I put it here for specificity
    config.Routes.MapHttpRoute(
         name: "DefaultWeek",
         routeTemplate: "api/week",
         defaults: new { controller = "Week", action="Get" }
    );

    config.Routes.MapHttpRoute(
         name: "ApiDefault",
         routeTemplate: "api/{controller}/{id}",
         defaults: new { controller = "Week", id = RouteParameter.Optional }
    );

My action:

[WeekFilter] // This filters out the year/month/day string and creates a DateTime
public IEnumerable<Week> Get(DateTime? week = null){...}

I have been trying for a while now, but I can't seem to get the "/api/week/" one to work.. I don't think there is a problem with my action (or the fact that it has an optional parameter), but the routing seems to be wrong, yet I can't figure out why...

Thanks for your help!

EDIT:

The WeekFilter:

public class WeekFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var year = actionContext.ControllerContext.RouteData.Values["year"] as string;
        var month = actionContext.ControllerContext.RouteData.Values["month"] as string;

        if (!string.IsNullOrEmpty(year) && !string.IsNullOrEmpty(month))
        {
            var day = actionContext.ControllerContext.RouteData.Values["day"] as string;
            if (string.IsNullOrEmpty(day)) 
                day = "1";

            var datum = new DateTime(int.Parse(year), int.Parse(month), int.Parse(day));
            actionContext.ActionArguments["week"] = datum;
        }

        base.OnActionExecuting(actionContext);
    }
}

The action:

[WeekFilter]
public IEnumerable<Week> Get(DateTime? week = null)
{
    return HandlerLocator.GetQueryHandler<IGetWeeksDataHandler>().Execute(week);
}

By changing your DateTime? week DateTime? week parameter to have a default value of null both your routes are working:

[WeekFilter] 
public IEnumerable<Week> Get(DateTime? week = null)
{
    return null;
}

When you call your controller with api/week , the week parameter on your action method is null . You could change this by modifying your WeekFilter to initialize week if year and month are empty.

If you call it with /api/week/2013/8/13 everything works as expected.

I found my mistake.

In my global asax, I had:

   FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
   RouteConfig.RegisterRoutes(RouteTable.Routes);
   WebApiConfig.RegisterRoutes(GlobalConfiguration.Configuration);
   BundleConfig.RegisterBundles(BundleTable.Bundles);

But apparently the location of the web Api routing matters, I changed it to

   WebApiConfig.RegisterRoutes(GlobalConfiguration.Configuration);
   FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
   RouteConfig.RegisterRoutes(RouteTable.Routes);       
   BundleConfig.RegisterBundles(BundleTable.Bundles);

and now it works!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM