You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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/API/emodata错误截图
  • 请求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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 08:35:56