razor pages 不是 mvc 简化版,而是独立端点模型:@page 必须首行、pages/ 下、配 maprazorpages();@model 需全限定名;数据加载须在 onget;路由由 @page 优先控制。

Razor Pages 不是 MVC 的简化版,它压根不走控制器那一套——@page 一写,文件自己就成了端点,OnGet 就是入口,没控制器、没路由注册、没视图查找逻辑。
为什么新建页面后访问 404?
最常见原因是模板选错或结构不全。Visual Studio 里右键添加时,必须选“Razor 页面”,不是“Razor 视图”或“空文件”。选错就只生成 PizzaList.cshtml 单文件,缺 PizzaList.cshtml.cs 后置类,也没 @page 指令。
-
@page必须是.cshtml文件的第一行,前面不能有空行、注释或空白字符,否则编译报错:The 'page' directive must be the first content in the file - Pages 文件夹外建的页面默认不被识别,路径必须在
Pages/下(如Pages/Contact.cshtml→ 可访问为/Contact) -
Program.cs中漏掉MapRazorPages(),哪怕文件结构全对,照样 404
@model 类型匹配总失败?
这不是拼写疏忽,而是运行时强类型校验:Razor 引擎会比对 @model 声明和后置类的完整签名,差一个命名空间或大小写就炸。
-
PizzaList.cshtml写:@model ContosoPizza.Pages.PizzaListModel - 对应
PizzaList.cshtml.cs必须是:namespace ContosoPizza.Pages { public class PizzaListModel : PageModel { ... } } - 漏写
namespace、用小写pizzalistmodel、或只写@model PizzaListModel(没全限定名),都会触发InvalidOperationException: The model item passed into the ViewDataDictionary is of type '' but this ViewDataDictionary is for type ''
数据该在 OnGet 还是构造函数里加载?
必须在 OnGet 或 OnGetAsync 中加载。构造函数执行太早,HttpContext、依赖注入的服务、ModelState 都不可用。
- 构造函数适合做轻量初始化(比如赋默认值、注入服务字段),但不能调数据库、不能 await 异步操作
-
OnGet是第一个能安全使用 DI 服务、读取路由参数、写入ViewData或TempData的地方 - 带路径参数时,如
@page "/pizza/{id:int}",方法签名得是:public void OnGet(int id),框架自动绑定 - 别在
@{ }代码块里重复声明同名变量(如var Pizzas = new List<pizza>();</pizza>),会遮蔽@Model.Pizzas
路由怎么控制?靠文件路径还是 @page?
两者都管,但 @page 优先级更高。默认按文件路径映射,但你可以用 @page 覆盖它。
-
@page不带路径 → 路由 = 文件名(About.cshtml→/About) -
@page "/admin/users"→ 强制路由为/admin/users,和文件名无关 -
@page "/pizza/{id:int}"→ 支持整型约束,/pizza/abc直接 404,不进OnGet - 别在
Program.cs里配MapControllerRoute,Razor Pages 不认这个
最容易被忽略的是 @page 的位置和 @model 的全限定名——它们不是“写对了就行”,而是“差一个字符就崩”。调试时看到 404 或类型异常,先盯死这两处,比查 DI 配置快得多。










