简体   繁体   中英

ASP.NET Web Api url design

I try to use Web Api in an ASP.NET MVC4 application.

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {


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

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

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

    public class OrganisationApiController : ApiController
    {
        public List<Direction> GetDirections()
        {
            List<Direction> res = new List<Direction>();
            using (SerializerContext context = new SerializerContext())
            {
                res = context.DirectionSet.ToList();
            }
            return res;
        }

        public List<Departement> GetDepartements(int directionId)
        {
            List<Departement> res = new List<Departement>();
            using (SerializerContext context = new SerializerContext())
            {
                res = context.DepartementSet.Where(d => d.IdDirection == directionId).ToList();
            }
            return res;
        }
    }

Application starts with

protected void Application_Start()
        {           
            AreaRegistration.RegisterAllAreas();

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

When I develop I can call all my methods from OrganisationApiController : http://localhost:5000/api/OrganisationApi => GetDirections is called http://localhost:5000/api/OrganisationApi/GetDirections => GetDirections is called http://localhost:5000/api/OrganisationApi/GetDepartements/1 => GetDepartement is called with directionId = 1

But when I deploy on a server with IIS http://myserver.com:5000/api/OrganisationApi => GetDirections is called http://myserver.com:5000/api/OrganisationApi/GetDirections => GetDirections is called http://myserver.com:5000/api/OrganisationApi/GetDepartements/1 => 404 error

What I am missing?

You have a problem with those routes:

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

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

The second route is unnecessary (because the first one already handles those requests - id is specified as optional) and it has an error that you specifying that id is optional but the route doesn't contain an id at all.

Either remove the second route and change your action so it receive an optional parameter or replace them with:

config.Routes.MapHttpRoute(
                    name: "ActionIdApi",
                    routeTemplate: "api/{controller}/{action}/{id}",
                );

                config.Routes.MapHttpRoute(
                  name: "ActionApi",
                  routeTemplate: "api/{controller}/{action}",
                );

By the way your default rote is also very problematic because you are not specifying default controller and action - it supposed to be DEFAULT right...

From what i see here all your routes could be replaced with this one

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

Just replace your default values for controller and action.

EDIT:

The problem is in your action:

If you specify in your Route "id" parameter your action should be:

public List<Departement> GetDepartements(int id)

Parameter names must match.

Also you can combine both your actions into one action:

public List<Departement> GetDepartements(int? id)
        {
            List<Departement> res = new List<Departement>();
            using (SerializerContext context = new SerializerContext())
            {
                if(id.HasValue)
                {
                    res = context.DepartementSet.Where(d => d.IdDirection == directionId).ToList();
                }
                else
                {
                    res = context.DirectionSet.ToList();
                }
            }
            return res;
        }

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