ASP.NET MVC GET API路由未触发问题排查求助
问题描述
开发从数据库获取数据的GET API时,定义的路由始终无法触发,调整路由设置后仍无效。以下是相关代码文件及错误截图,请求排查问题原因并解决。
API控制器文件
using API_develop.Models; using Microsoft.Ajax.Utilities; using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.SqlClient; using System.Linq; using System.Net.Configuration; using System.Web; using System.Web.Mvc; namespace API_develop.Controllers { public class APIController : Controller { string congemp = ConfigurationManager.ConnectionStrings["Empconectionstring"].ConnectionString; // GET: API [HttpGet] [Route("API/emodata")] public IList<EMPdatalist> EMPdatalist() { IList<EMPdatalist> getdata = new List<EMPdatalist>(); { using (SqlConnection conn = new SqlConnection(congemp)) { using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = "SELECT id, firstname, lastname, email FROM Employees"; SqlDataAdapter da = new SqlDataAdapter(cmd); // Associate SqlCommand with SqlDataAdapter DataTable dt = new DataTable(); conn.Open(); da.Fill(dt); try { if (dt != null) { foreach (DataRow row in dt.Rows) { EMPdatalist emp = new EMPdatalist(); emp.Id = Convert.ToInt32(row["id"].ToString()); emp.FirstName = row["firstname"].ToString(); emp.LastName = row["lastname"].ToString(); emp.Email = row["email"].ToString(); getdata.Add(emp); } } } catch (Exception ex) { // Handle the exception (e.g., log it) Console.WriteLine(ex.Message); } finally { conn.Close(); } } } return getdata; } } } }
API模型类
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace API_develop.Models { public class EMPdatalist { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } public string Gender { get; set; } } }
RouteConfig.cs
using System.Web.Mvc; using System.Web.Routing; namespace API_develop { public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { action = "Index", id = UrlParameter.Optional } ); } } }
WebAPIConfig.cs
using System; using System.Web.Http; namespace API_develop { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings .Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept", "text/html", StringComparison.InvariantCultureIgnoreCase, true, "application/json")); } } }
错误截图
- 请求
api/API/emodata的错误:
- 请求
API/emodata的错误:
数据库脚本
USE [TokenAuthDB] GO /****** Object: Table [dbo].[Employees] Script Date: 7/5/2024 11:36:19 AM ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Employees]( [Id] [int] IDENTITY(1,1) NOT NULL, [FirstName] [nvarchar](max) NULL, [LastName] [nvarchar](max) NULL, [Email] [nvarchar](max) NULL, [Gender] [nvarchar](max) NULL, [CreatedDate] [datetime] NOT NULL, CONSTRAINT [PK_dbo.Employees] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO SET IDENTITY_INSERT [dbo].[Employees] ON INSERT [dbo].[Employees] ([Id], [FirstName], [LastName], [Email], [Gender], [CreatedDate]) VALUES (1, N'Benjamin', N'Jones', N'timothydavis@jennings.com', N'Male', CAST(N'2023-06-28T00:00:00.000' AS DateTime)) INSERT [dbo].[Employees] ([Id], [FirstName], [LastName], [Email], [Gender], [CreatedDate]) VALUES (2, N'David', N'Welch', N'lnelson@maldonado.net', N'Female', CAST(N'2020-04-07T00:00:00.000' AS DateTime)) INSERT [dbo].[Employees] ([Id], [FirstName], [LastName], [Email], [Gender], [CreatedDate]) VALUES (3, N'Jason', N'Young', N'powellrebecca@hotmail.com', N'Male', CAST(N'2019-06-19T00:00:00.000' AS DateTime)) INSERT [dbo].[Employees] ([Id], [FirstName], [LastName], [Email], [Gender], [CreatedDate]) VALUES (4, N'Brandon', N'Oneill', N'caseykennedy@yahoo.com', N'Male', CAST(N'2021-07-21T00:00:00.000' AS DateTime)) GO INSERT [dbo].[Employees] ([Id], [FirstName], [LastName], [Email], [Gender], [CreatedDate]) VALUES (100, N'Mark', N'Figueroa', N'timothy02@gmail.com', N'Male', CAST(N'2022-11-12T00:00:00.000' AS DateTime)) SET IDENTITY_INSERT [dbo].[Employees] OFF GO
问题原因及修复方案
核心问题
控制器继承了Controller(MVC控制器基类),但Web API需要继承ApiController(Web API专属基类)。MVC与Web API是两套独立的路由机制,当前控制器被MVC路由解析,导致Web API的自定义路由规则无法生效。
修复步骤
1. 修改控制器基类
将控制器的基类替换为ApiController,同步调整命名空间引用:
// 替换 using System.Web.Mvc; 为 using System.Web.Http; using System.Web.Http; namespace API_develop.Controllers { // 继承 ApiController 而非 Controller public class APIController : ApiController { string congemp = ConfigurationManager.ConnectionStrings["Empconectionstring"].ConnectionString; [HttpGet] [Route("API/emodata")] public IList<EMPdatalist> EMPdatalist() { IList<EMPdatalist> getdata = new List<EMPdatalist>(); using (SqlConnection conn = new SqlConnection(congemp)) { using (SqlCommand cmd = conn.CreateCommand()) { cmd.CommandText = "SELECT id, firstname, lastname, email FROM Employees"; SqlDataAdapter da = new SqlDataAdapter(cmd); DataTable dt = new DataTable(); conn.Open(); da.Fill(dt); try { if (dt != null && dt.Rows.Count > 0) { foreach (DataRow row in dt.Rows) { EMPdatalist emp = new EMPdatalist(); emp.Id = Convert.ToInt32(row["id"]); emp.FirstName = row["firstname"].ToString(); emp.LastName = row["lastname"].ToString(); emp.Email = row["email"].ToString(); getdata.Add(emp); } } } catch (Exception ex) { // 建议用日志框架记录异常,而非Console.WriteLine } finally { conn.Close(); } } } return getdata; } } }
2. 调整路由注册顺序
在Global.asax中,必须先注册Web API路由,再注册MVC路由,否则MVC路由会优先匹配请求:
protected void Application_Start() { // 先注册Web API路由 GlobalConfiguration.Configure(WebApiConfig.Register); // 再注册MVC路由 RouteConfig.RegisterRoutes(RouteTable.Routes); }
3. 验证请求路径
修复后可通过以下路径访问API:
http://你的域名/API/emodata(匹配自定义路由)http://你的域名/api/API/EMPdatalist(匹配Web API默认路由)
额外优化建议
- 异常处理:不要用
Console.WriteLine记录异常,改用NLog、Serilog等日志组件写入日志文件或数据库,方便排查问题。 - 数据转换:直接使用
Convert.ToInt32(row["id"]),无需先转字符串再转整数,减少性能开销和潜在错误。 - 连接字符串检查:确认
Empconectionstring拼写正确(建议改为EmpConnectionString,符合命名规范),避免数据库连接失败。
内容的提问来源于stack exchange,提问作者Abu Bakar Afzal
相关产品推荐
相关产品推荐

