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" }
);
}
Try assigning a null to your method parameter indicating that is optional
public IEnumerable<LocationFilterViewModel> GetLocations(int? id = null)