作为.NET Core 2.0发行版的一部分,还有一些ASP.NET的更新。其中之一是添加了一个新的Web框架来创建“页面”,而不需要复杂的ASP.NET MVC。新的Razor页面是一个比较简单的MVC框架版本,在某些方面是老的“.aspx” WebForms的演变。

在本文中,我们将介绍使用ASP.NET Razor页面和MVC的一些细节。

  • Razor页面基础知识

  • ASP.NET MVVM vs MVC

  • Razor页面的优点和缺点

  • 使用Handlers实现多个GET、POST Action方法

  • 为什么您应该使用Razor Pages

  • ASP.NET Razor页面与MVC代码的区别

基础知识:什么是ASP.NET Razor页面?

Razor页面与ASP.NET MVC开发使用的视图组件非常相似,它们具有所有相同的语法和功能。

最关键的区别是模型和控制器代码也包含在Razor页面中。它更像是一个MVVM(Model-View-ViewModel)框架,它支持双向数据绑定,更简单的开发体验,具有独立的关注点。

下面是一个Razor页面最基本的示例,在@functions块中内嵌代码,不过推荐将PageModel代码放在一个单独的文件中。这更像是我们在ASP.NET WebForms文件中编写代码的方式。

@page
@model IndexModel
@using Microsoft.AspNetCore.Mvc.RazorPages@functions {public class IndexModel : PageModel{public string Message { get; private set; } = "In page model: ";public void OnGet(){Message += $" Server seconds  { DateTime.Now.Second.ToString() }";}}
}<h2>In page sample</h2><p>@Model.Message</p>

我们现在两个选择:ASP.NET MVVM 或 MVC

我们现在有两个选择,一个MVC,另一个是MVVM框架。我不打算介绍MVC vs MVVM的所有细节。在这篇文章中用一些例子很详细说明了这一点。MVVM框架最关注的是数据模型的双向绑定。

MVC适用于具有大量动态服务器视图、单页应用程序、REST API和AJAX调用的应用程序。Razor页面非常适用于只读或执行基本数据输入的简单页面。

MVC最近在大多数编程语言的Web应用程序中非常流行,但是它也有其利弊。ASP.NET WebForms被设计为一个MVVM解决方案,您可以认为Razor页面是WebForms的演变。

Razor页面的优点和缺点

我(Matt Watson)一直在做ASP.NET开发大约15年了,精通所有的ASP.NET框架。根据我在使用新的Razor页面过程中,下面是我总结的利弊以及我是如何看待使用它们。

优点:更有条理,更少的“潜规则”

我不知道您,但是我第一次使用ASP.NET MVC,花了很多时间试图弄清楚它是如何工作的。命名规则和动态创建路由导致了很多我不习惯的规则。事实上,从路径“/Home/”到HomeController.Index(),它从“Views\Home\Index.cshtml”中加载一个视图文件,在刚开始使用时觉得很神奇。

Razor页面没有任何“潜规则”,文件更有条理。您有一个Razor视图和后台代码文件,就像WebForms一样,不像与MVC对应的控制器、视图和模型存放在不同目录中具有单独的文件。

MVC项目和Razor页面项目比较(将在本文后面介绍更多的代码差异)。

MVC与Razor页面文件比较

优点:单一责任

如果您以前曾经使用过MVC框架,您可能会看到一些巨大的控制器类,其中包含许多不同的Action。它们就像一种随着时间的推移而增加的病毒。

使用Razor页面,每个页面都是独立的,视图和代码组织在一起,这遵循单一责任原则。

使用Handlers实现多个GET、POST Action

默认情况下,Razor页面设计为具有单个OnGetAsyncOnPostAsync Action方法;如果您想在单个页面中具有不同的Action,则需要使用所谓的Handler。如您的页面有AJAX回调、多个表单提交或其它场景,则需要使用它。

例如,如果您使用Kendo Grid并希望通过AJAX调用加载Grid数据,则需要使用Handler来处理该AJAX调用。任何类型的单页面应用程序将使用大量Handler,或者您将所有这些AJAX调用指向MVC控制器。

我在页面中添加了一个名为OnGetHelloWorldAsync()的方法,我们该怎么调用它?

从我的研究来看, 调用Handler有三种不同的方式:

  1. Querystring – 示例:“/managepage/2177/?handler=helloworld”

  2. 为视图中的定义路由:@page"{handler?}",然后在Url中包括“/helloworld”

  3. 在视图中定义提交按钮 - 示例:<input type="submit" asp-page-handler="JoinList" value="Join" />

可以在这里了解更多有关单页面多个Handlers 的方式。

为什么您应该使用Razor页面的!

Razor页面是网页应用程序中的完美解决方案,我可能提出一个争议。它一目了然,你的应用程序中的任何HTML“页面”都是真实的页面。目前,MVC Action 可以返回HTML视图、JSON、文件或任何内容。使用Razor页面将页面加载和AJAX回调的服务之间强制分离

想想,这种强制分离解决了很多问题。

Razor Page MVC
HTML Views REST API calls, SOA

这将阻止MVC控制器包含大量的Action,MVC应用程序中的Action混合了不同的“页面”,而且还包含AJAX回调和其它功能。

当然,我还没有实际中使用这种开发方式,这可能是失败,也可能是成功的,只有时间才能告诉社区如何使用Razor页面。

ASP.NET Razor页面与MVC的代码比较

作为Razor页面的一部分,我在MVC和Razor页面中构建了一个非常简单Form表单。让我们来看看之间的代码。它只有一个文本框和提交按钮。

这是MVC视图:

@model RazorPageTest.Models.PageClass<form asp-action="ManagePage"><div class="form-horizontal"><h4>Client</h4><hr /><div asp-validation-summary="ModelOnly" class="text-danger"></div><input type="hidden" asp-for="PageDataID" /><div class="form-group"><label asp-for="Title" class="col-md-2 control-label"></label><div class="col-md-10"><input asp-for="Title" class="form-control" /><span asp-validation-for="Title" class="text-danger"></span></div></div><div class="form-group"><div class="col-md-offset-2 col-md-10"><input type="submit" value="Save" class="btn btn-default" /></div></div></div></form>

这是MVC控制器(数据模型是PageClass,只有两个属性,很简单)。

    public class HomeController : Controller{                   public IConfiguration Configuration;             public HomeController(IConfiguration config)                {Configuration = config;}                public async Task<IActionResult> ManagePage(int id)              {PageClass page;                      using (var conn = new SqlConnection(Configuration.GetConnectionString("contentdb"))){                            await conn.OpenAsync();                         var pages = await conn.QueryAsync<PageClass>("select * FROM PageData Where PageDataID = @p1", new { p1 = id });page = pages.FirstOrDefault();}            return View(page);}[HttpPost][ValidateAntiForgeryToken]            public async Task<IActionResult> ManagePage(int id, PageClass page)                {                    if (ModelState.IsValid){                            try{                                   //Save to the databaseusing (var conn = new SqlConnection(Configuration.GetConnectionString("contentdb"))){                          await conn.OpenAsync();                              await conn.ExecuteAsync("UPDATE PageData SET Title = @Title WHERE PageDataID = @PageDataID", new { page.PageDataID, page.Title});}}                               catch (Exception){                                    //log it}                            return RedirectToAction("Index", "Home");}             return View(page);}}

现在我们来比较一下Razor页面。

Razor 页面:

    @page "{id:int}"@model RazorPageTest2.Pages.ManagePageModel    <form asp-action="ManagePage"><div class="form-horizontal"><h4>Manage Page</h4><hr /><div asp-validation-summary="ModelOnly" class="text-danger"></div><input type="hidden" asp-for="PageDataID" /><div class="form-group"><label asp-for="Title" class="col-md-2 control-label"></label><div class="col-md-10"><input asp-for="Title" class="form-control" /><span asp-validation-for="Title" class="text-danger"></span></div></div><div class="form-group"><div class="col-md-offset-2 col-md-10"><input type="submit" value="Save" class="btn btn-default" /></div></div></div></form>

这是Razor PageModel,也称之为后台代码:

    public class ManagePageModel : PageModel{            public IConfiguration Configuration;              public ManagePageModel(IConfiguration config)        {Configuration = config;}[BindProperty]              public int PageDataID { get; set; }[BindProperty]           public string Title { get; set; } public async Task<IActionResult> OnGetAsync(int id)            {                     using (var conn = new SqlConnection(Configuration.GetConnectionString("contentdb"))){                          await conn.OpenAsync();                           var pages = await conn.QueryAsync("select * FROM PageData Where PageDataID = @p1", new { p1 = id });                         var page = pages.FirstOrDefault();                this.Title = page.Title;                            this.PageDataID = page.PageDataID;}                            return Page();}                public async Task<IActionResult> OnPostAsync(int id)                   {                    if (ModelState.IsValid)                {                          try{                                      //Save to the databaseusing (var conn = new SqlConnection(Configuration.GetConnectionString("contentdb"))){                                     await conn.OpenAsync();                        await conn.ExecuteAsync("UPDATE PageData SET Title = @Title WHERE PageDataID = @PageDataID", new { PageDataID, Title });}}                            catch (Exception){                   //log it}                return RedirectToPage("/");}                       return Page();}}

差异解密

两者之间的代码几乎相同,以下是主要的区别:

  • MVC视图代码部分完全相同,除了Razor页面顶上的@page

  • ManagePageModel具有OnGetAsyncOnPostAsync方法,取代了MVC控制器中两个“ManagePage” Action;

  • ManagePageModel包含之前单独在PageClass中的两个属性。

在MVC中HTTP POST请求,将对象传递给MVC的Action(例如ManagePage(int id,PageClass page));使用Razor页面,可以使用数据双向绑定。为了让Razor页面正确地使用双向数据绑定,我两个属性(PageDataIDTitle)使用了[BindProperty]标记。

总结

我真的很喜欢Razor页面,可以看到在我正在开发的ASP.NET Core项目中使用它们。我喜欢Razor页面的原因是应用程序中的真实页面,并使用MVC实现所有AJAX/REST API。我承认还有其它功能,Razor页面实现不了。好消息是MVC是超级灵活的,但这也使得它变得更加复杂。Razor Pages的真正美丽是它的简单。

参考:

  • Introduction to Razor Pages in ASP.NET Core

  • .NET Core 2.0 Changes – 4 Key Things to Know

相关文章:

  • .NET Core 2.0 正式发布信息汇总

  • .NET Standard 2.0 特性介绍和使用指南

  • .NET Core 2.0 的dll实时更新、https、依赖包变更问题及解决

  • .NET Core 2.0 特性介绍和使用指南

  • Entity Framework Core 2.0 新特性

  • 体验 PHP under .NET Core

  • .NET Core 2.0使用NLog

  • 升级项目到.NET Core 2.0,在Linux上安装Docker,并成功部署

  • 解决Visual Studio For Mac Restore失败的问题

  • ASP.NET Core 2.0 特性介绍和使用指南

  • .Net Core下通过Proxy 模式 使用 WCF

  • .NET Core 2.0 开源Office组件 NPOI

原文地址:http://www.cnblogs.com/tdfblog/p/asp-net-razor-pages-vs-mvc.html


.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注

ASP.NET Core Razor页面 vs MVC相关推荐

  1. ASP.NET Core Razor页面禁用防伪令牌验证

    这篇短文中,我将向您介绍如何ASP.NET Core Razor页面中禁用防伪令牌验证. Razor页面是ASP.NET Core 2.0中增加的一个页面控制器框架,用于构建动态的.数据驱动的网站:支 ...

  2. ASP.Net Core Razor 页面路由

    在服务器端 Web 应用程序框架中,其中非常重要的设计是开发人员如何将URL与服务器上的资源进行匹配,以便正确的处理请求.最简单的方法是将 URL 映射到磁盘上的物理文件,在 Razor 页面框架中, ...

  3. ASP.NET Core - Razor 页面介绍

    简介 随着ASP.NET Core 2 即将来临,最热门的新事物是Razor页面.在之前的一篇文章中,我们简要介绍了ASP.NET Core Razor 页面. Razor页面是ASP.NET Cor ...

  4. ASP.NET Core Razor 页面使用教程

    ASP.NET Core Razor 页面作为 ASP.NET Core 2.0的一部分发布,它是基于页面的全新的Web开发框架.如果您想学习如何使用 ASP.NET Core Razor 页面,可以 ...

  5. 使用EntityFramework Core和Enums作为字符串的ASP.NET Core Razor页面——第四部分

    目录 介绍 背景 使用代码 添加项目和项目技能处理 下载QuantumWeb-4.zip - 1.3 MB 介绍 这是一篇由多部分组成的文章的第四部分,演示了通过EntityFramework Cor ...

  6. 使用EntityFramework Core和Enums作为字符串的ASP.NET Core Razor页面——第三部分

    目录 介绍 使用代码 添加项目和项目状态处理 下载源文件 - 989.1 KB 介绍 这是一篇由多部分组成的文章的第三部分,演示了通过EntityFramework Core 2.1(EF)将C#en ...

  7. 使用EntityFramework Core和Enums作为字符串的ASP.NET Core Razor页面——第二部分

    目录 介绍 使用代码 完整的客户CRUD 客户创造 显示客户详情 编辑客户信息 删除客户记录 完整的初始化CRUD页面 下载源代码(QuantumWeb) 介绍 这是一篇由多部分组成的文章的第二部分, ...

  8. 使用EntityFramework Core和Enums作为字符串的ASP.NET Core Razor页面——第一部分

    目录 介绍 背景 开发环境 使用代码 开始构建UI和数据访问 EF迁移和数据库创建 摘要 创建初始对象模型和数据库并显示第一个Razor页面 下载源码(QuantumWeb) 介绍 这是一篇由多部分组 ...

  9. ASP.NET Core Razor 视图组件

    视图组件简介 在新的ASP.NET Core MVC中,视图组件类似于局部视图,但它们更强大.视图组件不使用模型绑定,仅依赖于您在调用时提供的数据. 视图组件特性: 呈现页面响应的某一部分而不是整个响 ...

最新文章

  1. Win7 Vista下的输入法问题
  2. 031_MessageBox弹框
  3. Zabbix介绍及安装部署
  4. KDD CUP 2018:中国团队包揽前三名,TOP1方案出炉
  5. 解决li在ie,firefox中行高不一致问题
  6. Javaspring 1-6课 基本概念及第一个Javaspring程序
  7. sql limit不接具体数字_MySQL的Limit 性能差?真的不能再用了?
  8. 2022最新H3CSE认证备考练习题,错过等明年
  9. android+vmware+wifi,笔记本使用wifi通过vmware workstation+openwrt 实现上网
  10. 【JAVA长虹键法】第十式 桥接模式(23种设计模式)
  11. 程序员更容易生女孩子,是不是真的?
  12. 套汇算法c语言,在金字塔下实现套利策略的测评
  13. 简单实现账号密码登录(写死了)
  14. BFC(Block Formatting Context) 及其如何工作
  15. 栈模拟递归 遍历二叉树的正确写法
  16. 使用js实现植物大战僵尸的一些基本功能
  17. m4r格式转换器免费版 V3.0
  18. Python_爬虫_网页图片下载_その日の紋
  19. Unity 批量修改命名(重命名)
  20. JAVA面试知识点个人整理

热门文章

  1. 《Java线程与并发编程实践》—— 2.3 谨防活跃性问题
  2. 在 Azure Functions 上使用不同的路由前缀
  3. 2021,我的输入输出
  4. 福利好礼现金大奖等你来→首届 .NET Conf China Hackathon 火热报名中!
  5. PowerToys插件扩展(类似Alfred)
  6. Dapr + .NET 实战(十四)虚拟机集群部署 mDNS + Consul
  7. 通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定...
  8. 联机分析的列式数据库 clickHouse
  9. BeetleX使用bootstrap5开发SPA应用
  10. .NET 5 开源工作流框架elsa技术研究