razor pages 是基于页面的路由模型,pagemodel 处理逻辑、.cshtml 负责渲染;正确添加需选“razor page”模板生成配对文件;路由由 pages 目录结构决定;onget/onpost 是核心处理器;绑定需 bindproperty 和 modelstate.isvalid 验证;重定向用 redirecttopage;tempdata 传临时数据;pagemodel 每请求新建,需注意 dbcontext 生命周期。

Razor Pages 不是“另一种 MVC”,它本质是基于页面的路由模型,PageModel 负责处理逻辑,.cshtml 负责渲染——用错地方(比如硬套 MVC 的 Controller/View 分离习惯)反而会让代码更难维护。
如何正确添加一个 Razor Page(不是 MVC View)
在 Visual Studio 中右键项目 → “添加” → “新项”,必须选 “Razor Page” 模板(不是“Razor View”或“Empty Page”)。这个操作会自动生成一对文件:Index.cshtml 和 Index.cshtml.cs,且后者继承自 PageModel。
- 手动创建
.cshtml文件但没配PageModel类?请求会 404,因为没有路由绑定 - 把
PageModel类放在非约定路径(如/Models/MyPage.cs)?运行时报InvalidOperationException: Could not find a page named '/MyPage' - 页面路径决定路由:
Pages/Products/Edit.cshtml默认对应/Products/Edit,不经过 Controller
OnGet() 和 OnPost() 是核心生命周期方法
Razor Pages 的请求处理不走 Action,而是由 PageModel 中的 OnGet()、OnPost() 等方法响应。它们不是普通方法,是框架按 HTTP 动词自动调用的“处理器”。
-
OnGet()必须是public,返回IActionResult(如Page()),否则页面无法加载 - 表单提交默认触发
OnPost(),但若表单含method="post"且无asp-page-handler,就只会调用无参数的OnPost() - 要支持多按钮提交(如“保存”和“删除”),用
asp-page-handler="Delete",对应OnPostDelete()方法 - 别在
OnGet()里写异步数据库查询却忘了加async Task<iactionresult></iactionresult>—— 同步阻塞会导致线程饥饿
模型绑定与验证必须显式启用
Razor Pages 默认不自动绑定复杂对象,也不自动触发数据注解验证,除非你主动传参并调用 TryValidateModel() 或使用 BindProperty 特性。
- 想让
OnPost()接收整个Product对象?必须给属性加[BindProperty],否则值始终为 null -
[Required]注解不会自动生效:需在OnPost()中先调用ModelState.IsValid判断,再决定是否保存 - 绑定集合(如
IList<item></item>)时,HTML name 必须严格匹配索引格式:name="Items[0].Name",否则模型绑定失败 - 禁用客户端验证?删掉
_ValidationScriptsPartial.cshtml引用即可,但服务端ModelState校验仍保留
跳转与状态传递容易踩的坑
Razor Pages 的重定向不推荐用 RedirectToAction(),而应优先用 RedirectToPage(),否则路由丢失、TempData 可能失效。
-
RedirectToPage("/Products/Index")正确;RedirectToAction("Index", "Products")错误(MVC 风格,找不到对应 Controller) - 跨页面传简单值,用路由参数:
RedirectToPage("/Products/Details", new { id = 123 }) - 传临时数据(如提示消息),用
TempData["Message"] = "Saved!",但必须在目标页的OnGet()中读取,且只读一次 -
ModelState不会跨请求保留,错误信息不能靠它传到下一个页面——得用TempData或隐藏字段
最常被忽略的是 PageModel 的生命周期:每个请求都新建实例,但它不是 Singleton 也不是 Scoped,没有内置依赖注入作用域管理——如果用了 IDbContextFactory<appdbcontext></appdbcontext> 却没显式 using,EF Core 连接可能泄漏。










