ASP.NET Core Razor页面 vs MVC

作为.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 PageMVC
HTML ViewsREST 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跨平台或扫描二维码关注

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/324021.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Gradle 简单使用

文章目录创建Gradle项目dependencies.gradlegradle.propertiesbuild.gradleGradle配置文件详解dependency-management 插件SpringBootPlugin 插件多模块热部署创建Gradle项目 dependencies.gradle ext.versions [ // 定义所有要使用的版本号springboot: 2.4.1 // Spri…

如何将HBuilder中的项目Push至Gitee中!

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。昨天&#xff0c;给大家介绍了下HBuilder中怎么从gitee中拉取项目至本地&#xff0c;需要的小伙伴们可以点击链接查看&#xff1a;如何从Gitee中拉取项目到HBuilder中&#xff1f;今天&…

PLEASE小组KTV点歌系统简要说明

PLEASE小组KTV项目指导老师&#xff1a;穆老师 班主任&#xff1a;佟老师小组成员&#xff1a;组长&#xff1a;徐祥 副组长&#xff1a;孟祥帅组员&#xff1a;董经纬 组员&#xff1a;孙晓文 周航 组员&#xff1a;徐龙一 张远远制作周期&#xff1a;2021年6月25日…

C#使用Xamarin开发可移植移动应用(5.进阶篇显示弹出窗口与通讯中心)附源码

源码地址:https://github.com/l2999019/DemoApp 可以Star一下,随意 - - 说点什么.. 没啥好说的.开干吧. 今天的学习内容? 今天的内容比较简单. 就几个弹出框和内置的消息通讯中心. 如图: 正文 1.xamarin中的弹出窗 xamarin帮我们把各个系统的弹出窗做了2个统一的类. 1.…

Java Agent的隔离实现以及卸载时一些坑

转载自 Java Agent的隔离实现以及卸载时一些坑 在《一文带你了解Java Agent》中&#xff0c;让大家了解了Java Agent的来龙去脉&#xff0c;当通过attach方式去动态加载一个Java Agent时&#xff0c;Agent中的类会被加载到业务的虚拟机中&#xff0c;在使用完Agent的之后&am…

KTV阶段项目告一段落,让我们张开双臂迎接新阶段吧!!

经过两周的周期&#xff0c;KTV项目终于告一段落&#xff0c;今天进行了项目答辩&#xff0c;大家表现的都很棒哦&#xff0c;以下是对KTV项目的一个简要总结。各位老师&#xff0c;各位4班的同学们&#xff0c;以及各位其他班的同学&#xff0c;大家下午好&#xff0c;首先需要…

Orleans稍微复杂的例子—互动

我费力费心的翻译过官方的教程,但是本人英语词汇量不高,可是架不住电子词典啊…只要肯花时间,我这些内容谁都可以做出来.所以这个事例告诉我们一个道理,那就是码农有三好,钱多话少死得早.我也许只有后两好. 当初阿尔法狗在围棋上战胜人类的时候,人工智能一时大热,不管老小,都大…

(链表 栈 队列 递归)

文章目录链表反转链表删除点链表中给定值的结点栈和队列双向链表实现栈和队列数组实现队列获取栈的最小值用两个栈实现一个队列用两个队列实现一个栈递归链表 反转链表 &#xff08;反转单链表 反转双向链表&#xff09; public class Code01_ReverseList {public static cl…

一文带你了解Java Agent

转载自 一文带你了解Java Agent Java Agent这个技术&#xff0c;对于大多数同学来说都比较陌生&#xff0c;像个黑盒子。但是多多少少又接触过&#xff0c;实际上&#xff0c;我们平时用的很多工具&#xff0c;都是基于Java Agent实现的&#xff0c;例如常见的热部署JRebel&am…

P3834-【模板】可持久化线段树 1(主席树)

正题 评测记录&#xff1a;https://www.luogu.org/recordnew/lists?uid52918&pidP3834 题意 给定一个长度为n的序列&#xff0c;有m个询问&#xff0c;求一个区间内的第k小的树。 解题思路 我们先思考用线段树快速询问第k小的树 我们可以用权值线段树来处理第k小的树&…

点滴小组KTV点歌系统简介

‍‍20级青鸟四班 点滴小组指导老师&#xff1a;穆老师 班主任&#xff1a;佟老师小组成员&#xff1a;组长&#xff1a;路鑫 副组长&#xff1a;戴洁 王硕组员&#xff1a;马蓥芳 组员&#xff1a;徐圣乾组员&#xff1a;徐圣坤 组员&#xff1a;赵昌杰制作周期&#xff1a;…

迁移.net framework 工程到.net core

在迁移.net core的过程中&#xff0c;第一步就是要把.net framework 工程的目标框架改为.net core2.0&#xff0c;但是官网却没有提供转换工具&#xff0c;需要我们自己动手完成了。.net framework 工程迁移为.net core工程大体上有两种方案&#xff1a; 1.创建一个.net core的…

(归并排序 快排 堆)

文章目录归并排序递归方法实现非递归方法实现求数组的小和求数组的降序对个数快排荷兰国旗问题&#xff08;Partition过程&#xff09;快排1.0快排2.0快排3.0堆大根堆堆排序使用堆排序归并排序 递归方法实现 public class Code01_MergeSort {// 递归方法实现public static vo…

亦云小组KTV点歌系统简介

20级青鸟四班 亦云小组指导老师&#xff1a;穆老师 班主任&#xff1a;佟老师小组成员&#xff1a;组长&#xff1a;靳天宇组员&#xff1a;王晓丹 谢佳泽 王睿志 蒲璐颖 张铨政目录&#xff1a;1.首页 2.项目前台 3..项目后台总结&#xff1a;本次KTV项目总结。总体来说&…

学习手记(2018/7/14~2018/7/18)——快乐纪中

2018/7/14&#xff1a;普通的纪中一天 儿子兄弟表示法 将一颗多叉树转换为二叉树的方法&#xff0c;左子节点连原树的第一个儿子&#xff0c;右子节点连原树的右边的兄弟 适用范围&#xff1a;树形dp 数位dp常见方法 状态压缩 分类讨论记忆法&#xff08;记忆化搜索&#x…

Entity Framework Core 2.0 特性介绍和使用指南

前言 这是.Net Core 2.0生态生态介绍的最后一篇&#xff0c;EF一直是我喜欢的一个ORM框架&#xff0c;随着版本升级EF也发展到EF6.x&#xff0c;Entity Framework Core是一个支持跨平台的全新版本&#xff0c;可以用三个词来概况EF Core的特点&#xff1a;轻量级、可扩展、跨平…

图解elasticsearch原理转载自

转载自 图解elasticsearch原理 版本 elasticsearch版本: elasticsearch-2.x 内容 图解ElasticSearch 云上的集群 集群里的盒子 云里面的每个白色正方形的盒子代表一个节点——Node。 节点之间 在一个或者多个节点直接&#xff0c;多个绿色小方块组合在一起形成一个Elas…

零云九歌小组KTV点歌系统简介

指导老师&#xff1a;穆老师 班主任&#xff1a;佟老师小组成员&#xff1a;组长&#xff1a;张炜林 副组长&#xff1a;李钰组员&#xff1a;郑宪佳 宋翔 李兆勋 杜庆霖零云九歌目录&#xff1a;1.首页 2.项目前台 3..项目后台总结&#xff1a;本次KTV项目总结。总体来说&am…

Orleans简单配置

话说曾几何时,我第一次看到xml文件,心中闪过一念想:"这<>是什么鬼?"…用ini或者json多简单易懂,现在发觉作为配置文件,json有赶超xml的趋势.不过xml用多了,也觉得顺眼多了.不觉得<>难看了,反而它能折叠让我觉得组织起来也更方便了.这说明一个道理:不是你…

say小组KTV点歌系统简介

指导老师&#xff1a;穆老师 班主任&#xff1a;佟老师小组成员&#xff1a;组长&#xff1a;焦文宇 组员&#xff1a;窦倩 王晓凤 巩固 石虹蔓 田锋目录&#xff1a;1.首页 2.项目前台 3..项目后台总结&#xff1a;从5月25号开始的到6月10号结束&#xff0c;这期间我们遇…