Asp.net mvc 缺少可选参数时出现带区域-404的WebAPI路由错误

Asp.net mvc 缺少可选参数时出现带区域-404的WebAPI路由错误,asp.net-mvc,asp.net-web-api,asp.net-web-api-routing,Asp.net Mvc,Asp.net Web Api,Asp.net Web Api Routing,当我尝试在没有可选参数的情况下调用WebAPI控制器时,遇到了404错误。我尝试在Global.asax.cs中重新排序路由初始化命令,但没有成功。WebAPI在一个区域中,我注释了该区域的路由信息,因此它找不到该路由。以下是我所拥有的: 在WebApiConfig.cs中: public static void Register(HttpConfiguration configuration) { configuration.Routes.MapHttp

当我尝试在没有可选参数的情况下调用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);
    }
        public override void RegisterArea(AreaRegistrationContext context)
    {
        //context.MapRoute(
        //    "API_default",
        //    "API/{controller}/{action}/{id}",
        //    new { action = "Index", id = UrlParameter.Optional }
        //);
    }
        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" }))))
在APIAreaRegistration.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);
    }
        public override void RegisterArea(AreaRegistrationContext context)
    {
        //context.MapRoute(
        //    "API_default",
        //    "API/{controller}/{action}/{id}",
        //    new { action = "Index", id = UrlParameter.Optional }
        //);
    }
        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" }))))
在Global.asax.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);
    }
        public override void RegisterArea(AreaRegistrationContext context)
    {
        //context.MapRoute(
        //    "API_default",
        //    "API/{controller}/{action}/{id}",
        //    new { action = "Index", id = UrlParameter.Optional }
        //);
    }
        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" }))))
(请注意:我试过使用注释掉的行和上面的行,没有区别)

这是我的问题控制器:

        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);
    }
        public override void RegisterArea(AreaRegistrationContext context)
    {
        //context.MapRoute(
        //    "API_default",
        //    "API/{controller}/{action}/{id}",
        //    new { action = "Index", id = UrlParameter.Optional }
        //);
    }
        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,它将不再返回404错误,而是继续返回0节点,而不是返回当前节点的子节点。如果省略id=0,则返回404错误,即

/API/LocationFilterAPI/GetLocations/0-工作正常

/API/LocationFilterAPI/GetLocations-返回404

我在这个控制器中的其他每个API调用要么有一个必需的参数,要么根本没有参数,所有这些都工作得很好。整个下午我都在忙这个。如有任何见解,将不胜感激

谢谢

劳里

p、 下面是我的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" }
        );
    }

尝试为方法参数
指定一个空值,表示该参数是可选的

public IEnumerable<LocationFilterViewModel> GetLocations(int? id = null)
public IEnumerable GetLocations(int?id=null)

尝试为方法参数
指定一个空值,表示该参数是可选的

public IEnumerable<LocationFilterViewModel> GetLocations(int? id = null)
public IEnumerable GetLocations(int?id=null)

我猜如果末尾没有参数,它会将
GetLocations
作为其他路由的参数。您的
应用程序\u Start
也在注册MVC路由-您只显示了API路由。其他路由是什么样子的?我猜如果没有末尾的参数,它会将
GetLocations
作为其他路由的参数。您的
应用程序\u Start
也在注册MVC路由-您只显示了API路由。其他路线是什么样子的?