1

I'm running into a 404 Error when I try to call my WebAPI controller without an optional parameter. I've tried reordering the route initializion commands in the Global.asax.cs to no avail. The WebAPI is in an area and I comment out the area's routing information so it doesn't find that route. Here's what I have:

In WebApiConfig.cs:

        public static void Register(HttpConfiguration configuration)
    {
        configuration.Routes.MapHttpRoute("DefaultAPI",
            "API/{controller}/{action}/{id}",
            new { id = RouteParameter.Optional });

        // From http://weblogs.asp.net/fbouma/how-to-make-asp-net-webapi-serialize-your-llblgen-pro-entities-to-json
        var json = configuration.Formatters.JsonFormatter;
        json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
        json.SerializerSettings.ContractResolver = new DefaultContractResolver()
        {
            IgnoreSerializableInterface = true,
            IgnoreSerializableAttribute = true
        };

        var appXmlType = configuration.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
        configuration.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
    }

in APIAreaRegistration.cs:

        public override void RegisterArea(AreaRegistrationContext context)
    {
        //context.MapRoute(
        //    "API_default",
        //    "API/{controller}/{action}/{id}",
        //    new { action = "Index", id = UrlParameter.Optional }
        //);
    }

In Global.asax.cs:

        protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register); 
        //WebApiConfig.Register(GlobalConfiguration.Configuration); 
        WebApiConfig.RegisterSiteMap();

        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }

(Please note: I've tried using the commented-out line versus the one above it and no difference)

Here is my problematic controller:

        [HttpGet]
    public IEnumerable<LocationFilterViewModel> GetLocations(int? id)
    {
        LocationFilterCollection Locations = LocationFilterCollection.GetLocations(id.HasValue ? id.Value : 0);
        List<LocationFilterViewModel> myList = new List<LocationFilterViewModel>();
        foreach (LocationFilterEntity myEntity in Locations)
        {
            LocationFilterViewModel myModel = new LocationFilterViewModel();
            InitializeModel(myEntity, myModel);
            myList.Add(myModel);
        }
        return myList;
    }

And, finally, here is my View code:

@Html.Kendo().TreeView().Name("Locations").LoadOnDemand(false).DataTextField("LocationName").DragAndDrop(false).Checkboxes(true).AutoBind(true).ExpandAll(true).DataSource(dataSource => dataSource
.Model(model => model
.Id("LocationId")
.HasChildren("HasChildren"))
.Read(read => read.Url(@Url.HttpRouteUrl("DefaultAPI", new { controller="LocationFilterAPI", action="GetLocations" }))))

If I add id=0 after the action= statement, it no longer returns a 404 error, but instead of returning the children of the current nodes, it keeps returning the 0 node. If I omit the id=0, it returns a 404 error, i.e.

/API/LocationFilterAPI/GetLocations/0 - works fine

/API/LocationFilterAPI/GetLocations - returns 404

Every other API call I have in this controller either has a required parameter or no parameter at all, and all of these are working just fine. I've been banging my head against this all afternoon. Any insight would be greatly appreciated.

Thanks!

Laurie

p.s. To respond to comment, below, here is my RegisterRoutes method:

        public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "LibraryCategoryList",
            url: "Library/List/{id}/{id2}",
            defaults: new { controller = "Library", action = "List", id = UrlParameter.Optional,id2=UrlParameter.Optional }
            );
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new[] { "BFRDP.Controllers" }
        );
    }
1
  • I'd guess that without the parameter on the end, it is treating the GetLocations as the parameter for some other route. Your Application_Start is also registering MVC routes - you've only shown the API route. What do the other routes look like? Commented May 1, 2015 at 2:29

1 Answer 1

6

Try assigning a null to your method parameter indicating that is optional

public IEnumerable<LocationFilterViewModel> GetLocations(int? id = null)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.