带区域的 WebAPI 路由 - 缺少可选参数时出现 404 错误
WebAPI Routing with Area - 404 Error when missing optional parameter
当我尝试在没有可选参数的情况下调用我的 WebAPI 控制器时,我 运行 遇到了 404 错误。我尝试重新排序 Global.asax.cs 中的路由初始化命令,但无济于事。 WebAPI在一个区域,我注释掉了该区域的路由信息,所以它找不到那条路由。这是我拥有的:
在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);
}
在APIAreaRegistration.cs:
public override void RegisterArea(AreaRegistrationContext context)
{
//context.MapRoute(
// "API_default",
// "API/{controller}/{action}/{id}",
// new { action = "Index", id = UrlParameter.Optional }
//);
}
在Global.asax.cs中:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
//WebApiConfig.Register(GlobalConfiguration.Configuration);
WebApiConfig.RegisterSiteMap();
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
(请注意:我试过使用注释掉的那一行和上面那一行,没有区别)
这是我有问题的控制器:
[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;
}
最后,这是我的查看代码:
@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" }))))
如果我在 action= 语句后添加 id=0,它不再 returns 404 错误,而是返回当前节点的子节点,而不是返回 0 节点。如果我省略 id=0,它会 returns 一个 404 错误,即
/API/LocationFilterAPI/GetLocations/0 - 工作正常
/API/LocationFilterAPI/GetLocations - returns 404
我在这个控制器中的每个其他 API 调用要么有一个必需的参数,要么根本没有参数,所有这些都工作正常。我整个下午都在为这个问题苦苦思索。任何见解将不胜感激。
谢谢!
劳丽
p.s。为了回应评论,下面是我的 RegisterRoutes 方法:
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" }
);
}
尝试为您的方法参数分配一个 null indicating that is optional
public IEnumerable<LocationFilterViewModel> GetLocations(int? id = null)
当我尝试在没有可选参数的情况下调用我的 WebAPI 控制器时,我 运行 遇到了 404 错误。我尝试重新排序 Global.asax.cs 中的路由初始化命令,但无济于事。 WebAPI在一个区域,我注释掉了该区域的路由信息,所以它找不到那条路由。这是我拥有的:
在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);
}
在APIAreaRegistration.cs:
public override void RegisterArea(AreaRegistrationContext context)
{
//context.MapRoute(
// "API_default",
// "API/{controller}/{action}/{id}",
// new { action = "Index", id = UrlParameter.Optional }
//);
}
在Global.asax.cs中:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
//WebApiConfig.Register(GlobalConfiguration.Configuration);
WebApiConfig.RegisterSiteMap();
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
(请注意:我试过使用注释掉的那一行和上面那一行,没有区别)
这是我有问题的控制器:
[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;
}
最后,这是我的查看代码:
@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" }))))
如果我在 action= 语句后添加 id=0,它不再 returns 404 错误,而是返回当前节点的子节点,而不是返回 0 节点。如果我省略 id=0,它会 returns 一个 404 错误,即
/API/LocationFilterAPI/GetLocations/0 - 工作正常
/API/LocationFilterAPI/GetLocations - returns 404
我在这个控制器中的每个其他 API 调用要么有一个必需的参数,要么根本没有参数,所有这些都工作正常。我整个下午都在为这个问题苦苦思索。任何见解将不胜感激。
谢谢!
劳丽
p.s。为了回应评论,下面是我的 RegisterRoutes 方法:
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" }
);
}
尝试为您的方法参数分配一个 null indicating that is optional
public IEnumerable<LocationFilterViewModel> GetLocations(int? id = null)