ASP.NET MVC添加视图示例
ASP.NET MVC高效构建Web应用- 商品搜索 - 京东
视图(V)是一个动态生成HTML页面的模板,它负责通过用户界面展示内容。本节将修改HelloWorldController类,并使用视图模板文件,以干净地封装生成对客户端的HTML响应的过程。
我们将使用Razor视图引擎创建视图模板文件。基于Razor的视图模板具有.cshtml文件扩展名,并提供一种使用C#创建HTML输出的优雅方法。Razor将编写视图模板时所需的字符数和击键次数降至最低,并支持快速、流畅的编码工作流。目前,我们只需知道,Razor是MVC框架视图引擎,可以用来创建视图模板文件。
3.3.1 新建项目添加视图文件
这里,我们可以复制一份例3.1代码作为本节的实例,然后基于此项目逐渐丰富内容。
【例3.2】将视图添加到MVC项目
(1)复制一份例3.1的项目文件夹test到磁盘另外某个目录,然后进入复制后的test文件夹,双击test.sln打开项目。打开HelloWorldController.cs文件,查看VS向导生成的Index方法,代码如下:
public string Index(){return "This is my <b>default</b> action...";}
当前,Index方法返回硬编码的含HTML的字符串。我们更改一下 Index 方法,代码如下所示:
public ActionResult Index() //方法的类型改为ActionResult{return View(); //返回View方法的结果}
我们使用视图模板生成对浏览器的HTML响应,此时Index方法返回的是ActionResult(或派生自 ActionResult)的类,而不是字符串等基元类型。View方法是控制器类(即类Controller)的一个内部方法,声明如下:
protected internal ViewResult View();
由于HelloWorldController类继承自类Controller,因此可以使用类Controller中的View方法。该方法创建一个ViewResult对象,该对象将视图呈现给响应。
我们知道,MVC中的控制器负责处理HTTP请求并生成响应结果,现在我们返回一个ViewResult对象作为响应结果,说白了,就是给客户端浏览器一个视图。语句return View();告诉方法Index应使用视图文件来呈现对浏览器的响应。但由于未显式指定要使用的视图文件的名称,ASP.NET MVC就默认使用\Views\HelloWorld文件夹中的Index.cshtml视图文件。那么,接下来我们要添加一个Index.cshtml文件。
(2)准备添加视图文件Index.cshtml。在解决方案资源管理器中,右键单击“Views\HelloWorld”文件夹并单击“添加”,然后单击“具有布局的MVC 5视图页(Razor)”,此时出现“指定项名称”窗口,我们在“项名称”文本框中输入Index,如图3-13所示。
图3-13
点击“确定”按钮,出现“选择布局页”对话框,如图3-14所示。
图5‑10
在“选择布局页”对话框中,接受默认_Layout.cshtml,然后单击“确定”,此时将创建\test\Views\HelloWorld\Index.cshtml文件。在上面的对话框中,在左窗格中选择Views\Shared文件夹,如果另一个文件夹中有一个自定义布局文件,则可以选择它。
在VS中双击刚才新增的Index.cshtml,添加代码如下:
@{Layout = "~/Views/Shared/_Layout.cshtml";}@{ ViewBag.Title = "my mvc"; }<h2>hi</h2><p>Hello from our View Template!</p>
粗体部分就是我们添加的。符号@是视图引擎Razor中的一个标记,表示用来插入一段服务器端的编程语言代码,这里是C#语言,也就是插入一段C#代码。VS MVC的视图引擎有两种:ASPX(C#)和Razor(cshtml),建议以后都使用Razor视图引擎(VS2017中已经默认Razor引擎了)。原来<% %>用于ASPX引擎视图页中,作为插入C#代码的标识,而在Razor中用更简洁的@代替了。这样就可以在cshtml文件中使用C#代码了。所以我们知道,{ ViewBag.Title = "my mvc";}就是一段C#代码,意思是把字符串"my mvc"赋值给ViewBag.Title。ViewBag.Title就相当于一个全局变量,程序运行时,网页标题会取值这个全局变量值,这样ViewBag.Title所存储的字符串就可以显示在网页标题上了。我们可以打开Shared文件夹下的_Layout.cshtml,这个文件称为布局文件,在这个文件里有这么一句:
<title>@ViewBag.Title - 我的ASP.NET应用程序</title>
@ViewBag.Title就是显示全局变量ViewBag.Title中的内容。@不能省略,否则就是直接显示“ViewBag.Title”本身了。
再回到Index.cshtml,最后2行HTML代码没啥好讲的,就是显示在网页上的普通字符串而已。<h2>是HTML中的一个标签,代表heading level 2,用于表示一个二级标题。<p>表示段落标签,是HTML中用于定义段落的基本元素。
现在运行项目,在浏览器中输入URL:https://localhost:44308/HelloWorld/Index,运行结果如图3-15所示。
图3-15
可以看到,“my mvc”显示在浏览器标题栏上,而网页中也正确显示了“hi”和“Hello from our View Template!”两个硬编码的字符串。网页上方的“应用程序名称”“主页”“关于”和“联系方式”是4个网址链接,点击它们可以打开新的网页,这4个链接是布局自动生成的,下面我们来改变一下布局。
3.3.2 更改视图和布局页面
首先,需要更改页面顶部的“应用程序名称”链接。继续在刚才的项目中,转到解决方案资源管理器中的/Views/Shared文件夹,然后双击打开_Layout.cshtml文件。此文件称为布局页,它位于所有其他页面使用的共享文件夹中。
布局模板使你能够在一个位置指定网站的HTML容器布局,然后将它应用到网站中的多个页面。查找@RenderBody()行。RenderBody是一个占位符,在其中显示你创建的所有视图特定的页面,“包装”在布局页面中。例如,如果选择“关于”链接,Views\Home\About.cshtml视图将在方法内RenderBody呈现。
如果我们在布局页文件_Layout.cshtml中修改网页名称或网址链接,那将会在所有网页上发生效果。比如,我们在_Layout.cshtml中,修改<title></title>之间的内容如下:
<title>@ViewBag.Title - Movie App</title>
意思就是修改一下标题。然后再把“ActionLink("应用程序名称",…)”这一行的内容修改如下:
@Html.ActionLink("MVC Movie", "Index", "Movies", null, new { @class = "navbar-brand" })
意思就是修改一下网址链接的标题。此时运行项目,我们可以看到在标题栏中的页面标题也变为“Home Page - Movie App”了,而且主页上的第一个链接名称变为“MVC Movie”了,如图3-16所示。
这说明修改生效了。再单击“关于”链接,你也会看到该页面显示“MVC Movie”以及标题栏中的标题依旧有“Movie App”这样的字符串,如图3-17所示。
这就说明,我们能够在布局页文件_Layout.cshtml中进行更改,并让网站上的所有页面都反映新标题。那为何会所有页面都反映新标题呢?这是因为所有网页的源代码都包含了_Layout.cshtml了。比如,当我们第一次添加Views\HelloWorld\Index.cshtml文件时,它自动包含以下代码:
@{Layout = "~/Views/Shared/_Layout.cshtml";}
这几行代码就是显式地为Index.cshtml设置布局页_Layout.cshtml。那为何会自动包含这几行代码呢?这是因为在Views\_ViewStart.cshtml文件中指定了。Views\_ViewStart.cshtml文件定义了所有视图将使用的通用布局。如果不想让某个页面使用通用布局,我们可以注释掉或从该页面文件中删除该代码。比如,在Views\HelloWorld\Index.cshtml中注释掉布局引用:
@*@{Layout = "~/Views/Shared/_Layout.cshtml";}*@
其中是@*和*@用于注释。如果不想注释,也可以可以使用Layout属性设置不同的布局视图,或将它设置为null,这样将不会使用任何布局文件。
3.3.3 更改视图标题
了解了布局的来龙去脉。现在,让我们更改Index视图的标题,在项目中双击打开Views/HelloWorld/Index.cshtml,修改ViewBag.Title的赋值,代码如下:
@{ViewBag.Title = "Movie List";}
图3-18 |
ViewBag是一个可以在控制器和视图之间传递任意类型对象的动态对象,Title是ViewBag中的一个专门存储字符串的属性,除它以外,还有其他属性,以后会慢慢接触到。我们可以通过在控制器中设置ViewBag的属性值,然后在视图中使用ViewBag 来访问这些属性值。例如,在控制器中设置ViewBag.Title = "My Title",然后在视图中使用@ViewBag.Title 来访问这个属性值,这样就可以将数据从控制器传递到视图中。当然这种使用方式也可以应用在多个cshtml文件中,就像现在,我们在HelloWorld/Index.cshtml中将字符串"Movie List"赋值给ViewBag.Title,那么在Views/Shared/_Layout.cshtml文件中的代码:
<title>@ViewBag.Title - Movie App</title>
就可以引用到ViewBag.Title所存储的最新内容了。使用此方法ViewBag,可以轻松地在视图模板和布局文件之间传递其他参数。我们按Ctrl+F5运行项目,然后在浏览器地址栏中输入URL:https://localhost:44308/HelloWorld/,运行结果如图3-18所示。
可以看到浏览器标题已被更改为“Movie List - Movie App”。如果在浏览器中未看到更改,则可能正在查看缓存的内容,此时可以在浏览器中按 Ctrl+F5强制加载来自服务器的响应。浏览器标题使用的ViewBag.Title是我们在Index.cshtml 视图模板中设置的,并在布局文件_Layout.cshtml中添加附加的“- Movie App”所创建。现在,我们学会了通过Index.cshtml 和_Layout.cshtml来修改浏览器标题了。其实,凭借布局文件可以很容易地对应用程序中所有页面进行更改。
不过,本例显示的数据(即“Hello from our View Template!”消息)是硬编码的。MVC应用程序有一个“V”(视图),而我们已有一个“C”(控制器),但还没有“M”(模型)。以后,我们将学习如何创建数据库并从中检索模型数据,而不是直接硬编码数据。
3.3.4 将数据从控制器传递给视图
在学习数据库并讨论模型之前,让我们先讨论如何将信息从控制器传递到视图。调用控制器类以响应传入的URL 请求,控制器类通过编写代码,用于处理传入浏览器请求、从数据库中检索数据,并最终决定发送回浏览器的响应类型。最后,我们可以从控制器使用视图模板来生成HTML响应并设置浏览器的格式。
控制器负责提供所需的任何数据或对象,以便视图模板向浏览器呈现响应。最佳做法是视图模板绝不应该执行业务逻辑或直接与数据库交互。相反,视图模板应仅处理控制器提供给它的数据。保持这种“关注点分离”有助于保持代码干净、可测试且更易于维护。
我们回顾一下类HelloWorldController中的Welcome方法,目前代码如下:
public string Welcome(string name,float height, int age = 10){return HttpUtility.HtmlEncode("Hello " + name + ", your height:"+height+" and age:"+age);}
可见,参数name、height和age直接输出到浏览器。我们将控制器更改为使用视图模板,而不是让控制器以字符串的形式呈现此响应。视图模板将生成动态响应,这意味着你需要将适当的数据从控制器传递给视图以生成响应。为此,我们可以让控制器将视图模板所需的动态数据(参数)存储在ViewBag,随后视图模板可以访问的对象中ViewBag。
打开HelloWorldController.cs文件,并在Welcome方法中为ViewBag对象添加 name和 height的值。ViewBag是一个动态对象,这意味着可以将任何你想要的对象放入其中。ASP.NET MVC模型绑定系统会自动将命名参数(name和height)从地址栏中的查询字符串映射到方法中的参数。修改后的Welcome方法如下所示:
public ActionResult Welcome(string name,float height, int age = 10){ViewBag.name = "Hello " + name;ViewBag.h = "Height:"+ height.ToString();ViewBag.age = age;return View();}
现在,ViewBag对象包含将自动传递给视图的数据。接下来,需要一个欢迎视图页来展现这些参数数据。语句return View();告诉方法Welcome应使用视图文件来呈现对浏览器的响应,但由于未显式指定要使用的视图文件的名称,ASP.NET MVC就默认使用\Views\HelloWorld文件夹中的Welcome.cshtml视图文件。接下来,我们要添加一个Welcome.cshtml文件。右键单击 Views\HelloWorld文件夹并单击“ 添加”,然后单击“带有布局的MVC 5视图页(Razor)”,在“指定项的名称”对话框中,输入“Welcome”,然后单击“ 确定”。在“选择布局页”对话框中,接受默认_Layout.cshtml,然后单击“确定”。此时,将会在磁盘上创建test\Views\HelloWorld\ Welcome.cshtml文件。下面我们在Welcome.cshtml文件中添加代码如下:
@{ViewBag.Title = "Welcome";}<h2>You are welcome!</h2><ul>@for (int i = 0; i < ViewBag.age; i++){<li>@ViewBag.name,@ViewBag.h</li>}</ul>
首先在页面上显示字符串“You are welcome!”,然后使用一个for循环,该循环中显示的内容由@ViewBag.name和@ViewBag.h决定,并且它们的实际值由用户在URL中指定。运行项目,在浏览器地址栏中输入URL:
https://localhost:44308/helloWorld/welcome?name=tom&height=1.18&age=5
运行结果如图3-19所示。
图3-20
可以看到实际数据从 URL中获取,并使用模型绑定器传递给控制器。控制器将数据打包到对象中,ViewBag并将该对象传递给视图。然后,视图以HTML形式向用户显示数据。在这个实例中,我们使用ViewBag对象将数据从控制器传递到视图。
相关文章:

ASP.NET MVC添加视图示例
ASP.NET MVC高效构建Web应用- 商品搜索 - 京东 视图(V)是一个动态生成HTML页面的模板,它负责通过用户界面展示内容。本节将修改HelloWorldController类,并使用视图模板文件,以干净地封装生成对客户端的HTML响应的过程…...
自动驾驶中的路径跟踪:Python实现与技术解析
自动驾驶中的路径跟踪:Python实现与技术解析 一、路径跟踪是什么?为什么它至关重要? 路径跟踪(Path Tracking)是自动驾驶系统的关键部分之一,它负责确保车辆能够沿着预定义的轨迹行驶,同时稳定控制转向角度和速度。一个好的路径跟踪算法需要具备以下特点: 精准度:能…...
前端面试题目-高频问题集合
1.CSS里面水平垂直居中的方法 1.CSS里面水平垂直居中的方法弹性布局display: flex; /*先开启flex布局*/justify-content: center; /*实现水平居中*/jalign-items: center; /*实现垂直居中*/网格布局display: grid; /*先开启grid布局*/plac…...
MyBatis源码解析:从 Mapper 接口到 SQL 执行的完整链路
MyBatis源码解析:从 Mapper 接口到 SQL 执行的完整链路 一、Mapper 代理对象的创建:sqlSession.getMapper(UserMapper.class)二、接口方法的执行:mapper.selectUser("coderzpw", 18)2.1 四大核心组件解析2.1.1 Executor(…...

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Form Wave(表单label波动效果)
📅 我们继续 50 个小项目挑战!—— FormWave组件 仓库地址:https://github.com/SunACong/50-vue-projects 项目预览地址:https://50-vue-projects.vercel.app/ 🎯 组件目标 构建一个美观、动态的登录表单࿰…...

双目相机深度的误差分析(基线长度和相机焦距的选择)
全文基于针孔模型和基线水平放置来讨论 影响双目计算深度的因素: 1、基线长度:两台相机光心之间距离2、相机焦距(像素): f x f_x fx(或 f y f_y fy)为焦距 f f f和一个缩放比例的乘积。在…...

Pytorch Geometric官方例程pytorch_geometric/examples/link_pred.py环境安装教程及图数据集制作
最近需要训练图卷积神经网络(Graph Convolution Neural Network, GCNN),在配置GCNN环境上总结了一些经验。 我觉得对于初学者而言,图神经网络的训练会有2个难点: ①环境配置 ②数据集制作 一、环境配置 我最初光想…...

React---day6、7
6、组件之间进行数据传递 **6.1 父传子:**props传递属性 父组件: <div><ChildCpn name"蒋乙菥" age"18" height"1,88" /> </div>子组件: export class ChildCpn extends React.Component…...

hook组件-useEffect、useRef
hook组件-useEffect、useRef useEffect 用法及执行机制 WillMount -> render -> DidMount ShouldUpdate -> WillUpdate -> render -> DidUpdate WillUnmount(只有这个安全) WillReceiveProps useEffect(callback) 默认所有依赖都更新useEffect(callback, [])&am…...
功能结构整理
C# Sxer Sxer.Base:基础子功能 Sxer.Base.Debug:打印 Sxer.Utility:工具类 Sxer.CustomFunction:独立功能点开发 Unity...
企业级开发中的 maven-mvnd 应用实践
1. 引言:Maven 在企业级开发中的挑战 1.1 Maven 构建的常见痛点 在大型 Java 项目中,Maven 是主流的构建工具,但随着项目的复杂度增加,其性能瓶颈逐渐显现: 构建速度慢:每次执行 mvn clean install 都需要重新加载插件和依赖。重复构建浪费资源:即使未修改源码,仍会触…...
yolov12毕设前置知识准备 1
1 什么是目标检测呢? 目标检测(Object Detection)主要用于识别图像或视频中特定类型物体的位置,并标注其类别。 简单来说,就是让计算机像人类一样 “看懂” 图像内容,不仅能识别出物体(如人、…...

随机游动算法解决kSAT问题
input:n个变量的k-CNF公式 ouput:该公式的一组满足赋值或宣布没有满足赋值 算法步骤: 随机均匀地初始化赋值 a ∈ { 0 , 1 } n a\in\{0,1\}^n a∈{0,1}n.重复t次(后面会估计这个t): a. 如果在当前赋值下…...

《Discuz! X3.5开发从入门到生态共建》第1章 Discuz! 的前世今生-优雅草卓伊凡
《Discuz! X3.5开发从入门到生态共建》第1章 Discuz! 的前世今生-优雅草卓伊凡 第一节 从康盛创想到腾讯收购:PC时代的辉煌 1.1 Discuz! 的诞生:康盛创想的开源梦想 2001年,中国互联网正处于萌芽阶段,个人网站和论坛开始兴起。…...
azure web app创建分步指南系列之一
什么是 Azure Web 应用? Azure Web 应用是 Azure 应用服务的一部分,是一个完全托管的平台,用于开发、部署和扩展 Web 应用程序。它支持各种编程语言和框架,例如 .NET、Java、Python、PHP 和 Node.js,使开发人员能够构建强大的 Web 应用程序,而无需担心底层基础架构。借助…...
PyTorch实战——基于生成对抗网络生成服饰图像
PyTorch实战——基于生成对抗网络生成服饰图像 0. 前言1. 模型分析与数据准备2. 判别器3. 生成器4. 模型训练5. 模型保存与加载相关链接0. 前言 我们已经学习了生成对抗网络 (Generative Adversarial Network, GAN) 的工作原理,接下来,将学习如何将其应用于生成其他形式的内…...

笔试强训:Day6
一、小红的口罩(贪心优先级队列) 登录—专业IT笔试面试备考平台_牛客网 #include<iostream> #include<queue> #include<vector> using namespace std; int n,k; int main(){//用一个小根堆 每次使用不舒适度最小的cin>>n>&…...
【Hexo】4.Hexo 博客文章进行加密
安装 npm install --save hexo-blog-encrypt1-快速使用 将“ password”添加到您的文章信息头就像这样: password: 123456 ---2-按标签加密 1.修改文章信息头如下: title: Hello World tags: - 加密文章tag date: 2020-03-13 21:12:21 password: muyiio…...
Android --- ObjectAnimator 和 TranslateAnimation有什么区别
文章目录 2. 作用范围和功能2. 动画表现3. 是否修改 View 的属性4. 适用场景5. 性能总结: ObjectAnimator 和 TranslateAnimation 都是 Android 中常用的动画类型,但它们有以下几个关键的区别: 2. 作用范围和功能 ObjectAnimator:…...
小白的进阶之路系列之四----人工智能从初步到精通pytorch自定义数据集下
本篇涵盖的内容 在之前的文章中,我们已经讨论了如何获取数据,转换数据以及如何准备自定义数据集,本篇文章将涵盖更加深入的问题,希望通过详细的代码示例,帮助大家了解PyTorch自定义数据集是如何应对各种复杂实际情况中,数据处理的。 更加详细的,我们将讨论下面一些内容…...
安卓添加设备节点权限和selinux访问权限
# 1 修改设备节点权限及配置属性设置节点值 ## 1.1 修改设备节点权限 ### 1.1.1 不会手动卸载的节点 在system/core/rootdir/init.rc中添加节点权限 在on boot下面添加 chown system system /sys/kernel/usb/host chmod 0664 /sys/kernel/usb/host ### 1.1.2 支持热插拔的…...

谷歌Stitch:AI赋能UI设计,免费高效新利器
在AI技术日新月异的今天,各大科技巨头都在不断刷新我们对智能工具的认知。最近,谷歌在其年度I/O开发者大会期间,除了那些聚光灯下的重磅发布,还悄然上线了一款令人惊喜的AI工具——Stitch。这是一款全新的、完全免费的AI驱动UI&am…...

运营商地址和ip属地一样吗?怎么样更改ip属地地址
在互联网时代,IP属地和运营商地址是两个经常被提及的概念,但它们是否相同?如何更改IP属地地址?这些问题困扰着许多网民。本文将深入探讨这两个概念的区别,并详细介绍更改IP属地地址的方法。 一、运营商地址和IP属地一…...

在QT中,利用charts库绘制FFT图形
第1章 添加charts库 1.1 .pro工程添加chart库 1.1.1 在.pro工程里面添加charts库 1.1.2 在需要使用的地方添加这两个库函数,顺序一点不要搞错,先添加.pro,否则编译器会找不到这两个.h文件。 第2章 Charts关键绘图函数 2.1 QChart 类 QChart 是…...
ChatGPT + 知网 + 知乎,如何高效整合信息写出一篇专业内容?
——写作,不是闭门造车,而是高效聚合 🧠 为什么“信息整合力”才是AI时代的核心写作能力? 现在的写作,不缺工具,也不缺资料,缺的是: 把 scattered info 变成 structured idea 的能力…...

流媒体协议分析:流媒体传输的基石
在流媒体传输过程中,协议的选择至关重要,它决定了数据如何封装、传输和解析,直接影响着视频的播放质量和用户体验。本文将深入分析几种常见的流媒体传输协议,探讨它们的特点、应用场景及优缺点。 协议分类概述 流媒体传输协议根据…...

vscode中让文件夹一直保持展开不折叠
vscode中让文件夹一直保持展开不折叠 问题 很多小伙伴使用vscode发现空文件夹会折叠显示, 让人看起来非常难受, 如下图 解决办法 首先打开设置->setting, 搜索compact Folders, 去掉勾选即可, 如下图所示 效果如下 看起来非常爽 ! ! !...

JAVA-springboot整合Mybatis
SpringBoot从入门到精通-第15章 MyBatis框架 学习MyBatis心路历程 2022年学习java基础时候,想着怎么使用java代码操作数据库,咨询了项目上开发W同事,没有引用框架,操作数据库很麻烦,就帮我写好多行代码,就…...

深度学习pycharm debug
深度学习中,Debug 是定位并解决代码逻辑错误(如张量维度不匹配)、训练异常(如 Loss 波动)、数据问题(如标签错误)的关键手段,通过打印维度、可视化梯度等方法确保模型正常运行、优化…...

MicroPython+L298N+ESP32控制电机转速
要使用MicroPython控制L298N电机驱动板来控制电机的转速,你可以通过PWM(脉冲宽度调制)信号来调节电机速度。L298N是一个双H桥驱动器,可以同时控制两个电机的正反转和速度。 硬件准备: 1. L298N 电机控制板 2. ESP32…...