MVC中Controller向View传值的几种方式

news2024/12/29 10:56:20

MVC中Controller向View传值的几种方式


文章目录

  • MVC中Controller向View传值的几种方式
    • 一、ViewModel
      • 使用ViewModel
    • 二、ViewData
      • 在控制器和视图间使用ViewData传递数据
      • 在 ViewDataTest 视图中使用ViewData的数据
      • 在视图和部分视图间使用ViewData
    • 三、ViewBag
    • 四、TempData
    • 五、Session
    • 六、总结


一、ViewModel

ViewModel 是一个用来渲染 ASP.NET MVC 视图的强类型类,可用来传递来自一个或多个视图模型(即类)或数据表的数据。可将其看做一座连接着模型、数据和视图的桥梁。其生命期为当前视图。视图模型属于强类型,所以在VS中便有智能提示并且可以进行静态检测。

使用ViewModel

先创建一个用于呈现视图的视图模型类:

public class Student
{
    public int ID { get; set; }
    public string Name { get; set; }
    public DateTime Birth { get; set; }
}

在控制器中定义该类:

public IActionResult Index()
{            
    Student student=new Student()
    {
        ID = 1,
     Birth = new DateTime(2000,1,1),
        Name = "test"
    };
    return View(student);
}  

在视图中使用

Razor视图开头使用@model 指定强类型,使用了@model 的视图称为强类型视图,强类型视图可获得智能提示和静态检查。不使用@mdoel 则后面的 @Model 为动态类型,不会获得智能提示和静态检查。

同时强类型 Model 可使用辅助器方法,而弱类型 Model 不能使用辅助器方法,因为 c# 表达式树不能包含动态操作。

Index视图:

@model Student

<div>    
    @Html.DisplayNameFor(m=>m.ID)
    @Html.DisplayFor(m=>m.ID)
</div>
<div>
    Birth @Model.Birth
</div>
<div>
    Name @Model.Name
</div>

强类型视图:
在这里插入图片描述

在这里插入图片描述
弱类型视图缺少智能提示:

在这里插入图片描述
在这里插入图片描述

二、ViewData

ViewData是一个Dictionary<string,object>的字典,数据以键值对的形式存储在 ViewData 中。ViewData 用来在控制器和视图之间传递数据,也可以在视图和分部视图之间传递数据。其生存期为当前视图渲染结束。由于在使用 ViewData 时返回的是一个object对象,所以应用实际类型的属性或值时需要使用强制类型转换。当传递的数据作为字符串在视图中使用时不需要进行强制转换,因为 c# 每个对象存在 ToString 方法,而在 c# 视图中会自动调用该方法。

ViewData
View
PartialView
ViewData
Controller
View
ViewData
PartialView

除直接定义 ViewData[""] 外,ASP.NET Core 还支持对控制器中的属性使用
[TempData] 特性定义ViewData

但是 ViewData 不能用于跨请求的情形,即无法在跳转后的页面使用跳转前页面定义的 ViewData ,而后续提到的 TempData 可以用于跨请求的数据传递。

在控制器和视图间使用ViewData传递数据

public IActionResult ViewDataTest()
{
    ViewData["student"]=new Student()
    {
        ID = 1,
        Birth = DateTime.Now,
        Name = "test"
    };
    ViewData["Greeting"] = "Hello";
    return View();
} 

在 ViewDataTest 视图中使用ViewData的数据

@{
    Student student = ViewData["student"] as Student;
    ViewData["test"] = "test";
}

@ViewData["greeting"]
<div>ID: @student.ID</div>
<div>Name: @student.Name</div>
<div>Birth: @student.Birth</div>
<br/>
@Html.ActionLink("Test","Test")

用来测试跨请求的 Test 方法和视图:

public IActionResult Test()
{
    return View();
}
@{
    ViewData["Title"] = "Test";
}

<h2>Test</h2>

@ViewData["test"]   

直接使用 ViewData 中数据的属性:
在这里插入图片描述
在视图和部分视图间使用 ViewData 时,部分视图中的 ViewData 的定义不会覆盖原视图的 ViewData 。在视图和部分视图之间传递 ViewData 时,主要使用的是 PartialAsync 辅助器方法以及 <partial> 标记辅助器方法。

在视图和部分视图间使用ViewData

public static Task<IHtmlContent> PartialAsync(this IHtmlHelper htmlHelper, string partialViewName, ViewDataDictionary viewData)

第一个参数传入部分视图名称,第二个参数传入一个 ViewDataDictionary 对象。若不指定第二个参数,则会将当前视图的 ViewData 传入部分视图。

ViewDataTest2 视图:

 <h2>ViewDataTest2</h2>
 @{
      ViewData["Student"] = new Student()
      {
          ID = 1,
          Birth = DateTime.Now,
          Name = "test"
      };
      ViewData["Greeting"] = "Good morning";
 }
 
 View: @ViewData["Greeting"]
 <br/>
 @await Html.PartialAsync("PartialView",new ViewDataDictionary(ViewData))
 
 View: @ViewData["Greeting"]

PartialView 视图:

@{
    Student student = ViewData["Student"] as Student;
}

Partial: @ViewData["Greeting"]
<hr/>
<div>ID: @student.ID</div>
<div>Name: @student.Name</div>
<div>Birth: @student.Birth</div>
<hr/>
@{
    ViewData["Greeting"] = "Good afternoon";
}

<div>Partial: @ViewData["Greeting"]</div>

使用 partial 标记辅助器方法:

关于 partial 标记辅助器方法:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/views/partial?view=aspnetcore-2.1

使用时,为 name 属性传递部分视图的名称,为 view-data 属性传递 ViewDataDictionary 对象的名称:

<h2>ViewDataTest2</h2>
@{
    ViewData["Student"] = new Student()
    {
        ID = 1,
        Birth = DateTime.Now,
        Name = "test"
    };
    ViewData["Greeting"] = "Good morning";
}

View: @ViewData["Greeting"]
<br/>
@*@await Html.PartialAsync("PartialView",new ViewDataDictionary(ViewData))*@
<partial name="PartialView" view-data="ViewData" />
View: @ViewData["Greeting"]

结果和使用 PartialAsync 辅助器方法一致。

三、ViewBag

ViewBag 是一个包装了 ViewData 的动态类型,从 ControllerBase 继承而来,因此在视图页中也无法使用 ViewBag。由于 ViewBag 是一个动态对象,所以可以为其添加任意属性。也由于 ViewBag 属于动态类型,所以可以直接调用其中的属性进行操作。

ViewBagViewData 的区别在于:

  • 不能在视图页中传递特定的 ViewBag。
  • 在视图中虽然可以定义 ViewBag 在当前视图使用,但不能定义 ViewBag 传递到部分视图。

ViewBag 在 Razor 页中不可用。

ViewData

  1. 派生自 ViewDataDictionary,因此它有可用的字典属性,如 ContainsKey、Add、RemoveClear。字典中的键是字符串,因此允许有空格。 ViewData["Some Key With Whitespace"]
  2. 任何非 string 类型均须在视图中进行强制转换才能使用 ViewData

ViewBag

  1. 派生自 DynamicViewData,因此它可使用点表示法 (@ViewBag.SomeKey = <value or object>) 创建动态属性,且无需强制转换。 ViewBag 的语法使添加到控制器和视图的速度更快。(其实差不多)
  2. 更易于检查 NULL 值。 @ViewBag.Person?.Name
public IActionResult ViewBagTest()
{
    ViewBag.Student = new Student()
    {
		ID = 1,
		Birth = new DateTime(1997,1,1),
		Name = "test" 
    };
    return View();
}

ViewBagTest 视图:

 <h2>ViewBagTest</h2>
 
 <div>View: @(ViewBag.Student.ID+1)</div>
 
 @await Html.PartialAsync("_ViewBagPartial")

_ViewBagPartial 视图:

 <div>ID: @ViewBag.Student.ID</div>
 <div>Name: @ViewBag.Student.Name</div>
 <div>Birth: @ViewBag.Student.Birth</div>

四、TempData

TempData 是一个继承自 System.Web.Mvc.TempDataDictionary 的类型,是一个 Dictionary<string,object> 的字典。生命期为控制器中生命开始到该 TempData 被读取结束,即使重定向到另一个控制器的方法,只要一个 TempData 未被读取,它就仍然存在。在一个访问过 TempData 的页面进行刷新会再次访问该 TempData ,未被延长生命期的 TempData 将被删除。TempData 通常用于在动作方法之间传递数据(如错误信息)。

如果希望在一次访问后保留 TempData 对象,则需要在控制器的方法中调用 TempData.Keep 方法,或者在视图中使用 TempData.Peek 方法访问 TempData 对象。但是需要注意的是 TempData.Keep 方法不会延长重定向的视图中被访问的 TempData 对象的生命期。重定向的视图即指使用 RedirectXXX 抵达的视图。

由于 TempData 将它本身保存在 ASP.NETSession 中,因此需要谨慎使用,当将应用程序托管到多个服务器时 TempData 会出现问题。为解决该问题此时可选择在 session 的生命期内将用户的请求全部分配给同一个服务器,或者在服务器之间转发 session 信息。

除了使用 TempData[""]TempData 进行定义外,还可以使用对属性使用 [TempData] 修饰对 TempData 进行定义。

public IActionResult TempDataTest()
{
    TempData["error"] = "An error";
    TempData["greeting"] = "Hello";

    //将 TempData["error"] 生存期延长一次
    TempData.Keep("error");          

    return View();
}

public IActionResult ReceiveTempData()
{
    return View();
}

public IActionResult ReceiveTempData2()
{
    return View();
}

TempDataTest 视图:

 @{
     ViewData["Title"] = "TempDataTest";
 }
 
 <h2>TempDataTest</h2>
 
 <div>@TempData["error"]</div>
 
@*访问 TempData["greeting"] 并将 TempData["greetng"] 延长一次*@
 <div>@TempData.Peek("greeting")</div>
 <br/>
 <div>@Html.ActionLink("Another", "Index", "TempData")</div>
 @Html.ActionLink("ReceiveTempData","ReceiveTempData")

用来测试跨请求的 ReceiveTempData 视图:

 @{
     ViewData["Title"] = "ReceiveTempData";
 }
 
 <h2>ReceiveTempData</h2>
 
 <div>@TempData["error"]</div>
 
 @*将 TempData["greetng"] 生命期延长一次*@
 <div>@TempData.Peek("greeting")</div>
 <br/>@Html.ActionLink("ReceiveTempData2", "ReceiveTempData2")

ReceiveTempData2 视图:

 @{
     ViewData["Title"] = "ReceiveTempData2";
 }
 
 <h2>ReceiveTempData2</h2>
 
 <div>@TempData["error"]</div>
 <div>@TempData["greeting"]</div>

另一个控制器 TempDataController:

public class TempDataController : Controller
{
    public IActionResult Index()
    {
        return View();
    }
}

该控制器的 Index 视图:

@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<div>@TempData["error"]</div>

结果:

在这里插入图片描述

使用重定向:

public IActionResult TempDataTest()
{
    TempData["error"] = "An error";
    TempData["greeting"] = "Hello";
    TempData.Keep("error");
    //return View();
    return RedirectToAction("ReceiveTempData");
}

结果:
在这里插入图片描述
本应被延长的 TempData[“error”] 没有被延长。

五、Session

session 是从Web.SessionState 继承的键值对对象。在控制器之间传递数据,可用于跨请求状态下控制器和视图之间的数据传递。一般Session用于保留对特定用户的数据,但最好不要在其中放置敏感数据。生存期一直持续到 timeout 参数所限制的事件、调用Clear、RemoveAll、Abandon 方法或者关闭浏览器来明确地销毁它。最好减少 Session 的使用因为它在服务器集群环境下不可靠,并且在使用时将一直占用服务器资源。

在使用 Session 时需要在 Startup.cs 中对其进行配置(配置详情)。
在这里插入图片描述
使用方法:

在此我们将 Session 的过期时间设置为 5 秒,该过期时间在每次操作之后进行计算。

在 ConfigureServices 方法中:

services.AddDistributedMemoryCache();
services.AddSession(options =>
{
	options.IdleTimeout = TimeSpan.FromSeconds(5);
	options.Cookie.HttpOnly = true;
});

在 Configure 方法中:

 app.UseSession();
 app.UseMvc();

中间件的顺序很重要。

UseMvc 之后调用 UseSession 时会发生 InvalidOperationException 异常。

在默认的 ASP.NET Core 实现中,在 Session 中提供了字节流、int 以及 string 数据的获取和设置方法,分别为:

Get(ISession, String)
GetInt32(ISession, String)
GetString(ISession, String)
SetInt32(ISession, String, Int32)
SetString(ISession, String, String)

为了方便,分别实现一个 SetGetISession 泛型扩展方法:

public static void Set<T>(this ISession session, string key, T value)
{
    session.SetString(key, JsonConvert.SerializeObject(value));
}

public static T Get<T>(this ISession session, string key)
{
    var value = session.GetString(key);
    return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
}

控制器中:

  //用来获取和设置值的键
  public const string SessionKeyStudent = "_Student";

  public string AddSession()
  {
      if (HttpContext.Session.Get<Student>(SessionKeyStudent)==default(Student))
      {
          Student student=new Student()
          {
              Birth = new DateTime(1996,1,1),
              ID = 2,
              Name = "test"
          };
          HttpContext.Session.Set<Student>(SessionKeyStudent,student);
      }
      return "Session has been set";
  }

  public IActionResult SessionTest()
  {
      Student student = HttpContext.Session.Get<Student>(SessionKeyStudent) ?? new Student();           
      return View(student);
  }

SessionTest 视图:

@model Student
  @{
     ViewData["Title"] = "SessionTest";
 }
 
 <h2>SessionTest2</h2>

 <div>ID: @Model.ID</div>
 <div>Name: @Model.Name</div>
 <div>Birth: @Model.Birth</div>

六、总结

在这里插入图片描述

回到顶部


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

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

相关文章

搭建短链服务

目录 一、背景 1.1短链接的优势 1.1.1优点一 1.1.2优点二 1.1.3优点三 1.1.4优点四 1.1.4优点五 二、原理 2.1利用http重定向 3.1实现方案 3.1.1发号器实现 3.1.2存储实现 3.1.3映射实现 3.2架构图 一、背景 短链在互联网中盛行&#xff0c;搭建自己短链平台&…

硬件工程师-MOS管

MOSFET 场效应管 N管 P管 对标三极管 N管 P管 三极管具有功率放大的作用 MOSFET也具有功率作用&#xff0c; 控制级的电流很小 控制信号的内阻大 输出级的电流很大 输出信号的内阻很小 三极管的缺点&#xff1a;流控…

Blender 建模键盘(PS修图、UV贴图、Cycles渲染引擎)

目录 1. 键盘模型1.1 键盘底座1.2 底座细节1.3 logo位置1.4 键盘按键1.5 按键添加1.6 合并按键 2. 贴图、渲染2.1 到PS添加按键文字2.2 保存png图片2.3 图像纹理2.4 UV编辑2.5 添加平面2.6 添加环境纹理2.7 灯光、摄像机2.8 渲染属性2.9 渲染出图 1. 键盘模型 原图 1.1 键盘底…

三、IOC容器(2)

四、IOC操作Bean管理&#xff08;xml注入集合属性&#xff09; 4.在集合里面设置对象类型值 ①Course类 ②Stu类 ③配置xml文件 ④测试 5.把集合注入部分提取出来 在Spring配置文件中引入名称空间 util 2.使用util标签完成list集合注入 ①提取list集合类型的属性注入 <…

如何调整碳化硅 MOSFET 驱动来减少功率损耗

如何调整碳化硅 MOSFET 驱动来减少功率损耗 1.如何减少传导损耗&#xff1f;2.如何减少开关损耗&#xff1f;2.1 关断损耗 (Eoff) 取决于 Rg 和 Vgs-off2.2 开通损耗 (Eon) vs. Rg2.3 开通损耗 Eon 和反向恢复损耗 Err 的米勒效应2.4 对驱动电流的要求 作者&#xff1a;Xiou 参…

销售/回收DSOS254A是德keysight MSOS254A混合信号示波器

Agilent DSOS254A、Keysight MSOS254A、 混合信号示波器&#xff0c;2.5 GHz&#xff0c;20 GSa/s&#xff0c;4 通道&#xff0c;16 数字通道。 ​Infiniium S 系列示波器 信号保真度方面树立新标杆 500 MHz 至 8 GHz 出色的信号完整性使您可以看到真实显示的信号&#xff1…

远程桌面连接不上解决方法

远程桌面连接是一种方便快捷的技术&#xff0c;可以让用户在不同的设备之间共享桌面和访问远程计算机。然而&#xff0c;有时候我们可能会遇到远程桌面连接无法正常连接的问题。在本篇文章中&#xff0c;我们将详细介绍远程桌面连接无法连接的常见原因&#xff0c;并提供相对应…

0601-指针的基础

内存 物理存储器和存储地址空间 物理存储器&#xff1a;实际存在的具体存储器芯片。比如&#xff1a;内存条、RAM芯片、ROM芯片。 存储地址空间&#xff1a;对存储器编码的范围。 编码&#xff1a;对每个物理存储单元&#xff08;一个字节&#xff09;分配一个号码寻址&…

520网络情人节:用双语告白你的女神男神!

网络情人节&#xff08;Network Valentines Day&#xff09;——520、521被喻为“我愿意、我爱你” 的意思&#xff0c;又被称为“结婚吉日”、“表白日”、“撒娇日”、“求爱节”。每年5月20日和5月21日的“网络情人节”也成为了情侣们扎堆登记结婚、隆重举办婚宴 的吉日。 5…

系统分析师经典易错题,解题思路一

数据库通常采用三级模式结构,其中,视图对应外模式,基本表对应模式,存储文件对应内模式。数据的独立性是由DBMS的二级映像功能来保证的。数据的独立性包括数据的物理独立性和数据逻辑独立性。数据的物理独立性是指当数据库的内模式发生改变时,数据的逻辑结构不变。为了保证…

HTML获取SpringBoot从model传的值

controller层如下&#xff1a; html获取格式&#xff1a;[[${传入的值}]] 效果图&#xff1a;

Mybatis操作数据库执行流程的先后顺序是怎样的?

MyBatis是一个支持普通SQL查询、存储及高级映射的持久层框架&#xff0c;它几乎消除了JDBC的冗余代码。使Java开发人员可以使用面向对象的编程思想来操作数据库。对于MyBatis的工作原理和操作流程的理解&#xff0c;我们先来看下面的工作流程图。 MaBatis的工作流程 在上图中…

VMware和Ubuntu20.04的安装

VMware安装&#xff1a; 1、下载好VM后右击管理员运行&#xff1a; PS&#xff1a;推荐大家去官网下载&#xff0c;如果需要许可密钥的话&#xff0c;可以去搜一下&#xff0c;或者私信一下UP&#xff0c;链接放下面了。 VM官网 因为我已经安装好了&#xff0c;所以就不在贴…

Appium自动化环境搭建保姆级教程

APP自动化测试运行环境比较复杂&#xff0c;稍微不注意安装就会失败。我见过不少朋友&#xff0c;装了1个星期&#xff0c;Appium 的运行环境还没有搭好的。 搭建环境本身不是一个有难度的工作&#xff0c;但是 Appium 安装过程中确实存在不少隐藏的比较深的坑&#xff0c;如果…

5.1图的物理结构与基本操作

1.图的物理结构 一.邻接矩阵存储稠密图 用于存储无向图&#xff0c;有向图&#xff0c;总之各类图 优缺点&#xff1a;适合存储稠密图&#xff0c;属于上下三角矩阵&#xff0c;有重复 复杂度&#xff1a;O(V),空间O(V^2) 性质&#xff1a;阶乘得到某一点的值&#xff0c;为顶…

C语言入门级小游戏——三子棋

文章目录 游戏文件的创建游戏菜单重头戏&#xff0c;游戏正式开始棋盘的创建数据清空打印棋盘 玩家下棋电脑下棋输赢的判断1.赢2.平局&#xff0c;游戏继续 代码展示 今天我们写一个小游戏——三子棋来增加我们对编程的兴趣&#xff0c; 希望这篇文章对友友们有帮助! 游戏文件的…

测试进阶-软件测试的分类

目录 按照测试对象划分界面测试 *可靠性测试如何进行可靠性测试 容错性测试文档测试兼容性测试 *易用性测试 *安装卸载测试 *安全测试性能测试内存泄漏测试 按照是否查看代码划分黑盒测试白盒测试灰盒测试 按照开发阶段划分测试金字塔单元测试集成测试系统测试回归测试冒烟测试…

行政前台快递管理软件使用教程

行政前台快递如何管理&#xff0c;是每个行政人员永远避不开的话题。 不管是从行政相关的论坛中&#xff0c;还是从身边从事行政相关工作的亲友口中&#xff0c;亦或是某些公司前台堆积的快递&#xff0c;我们都能看到、听到行政相关人员抱怨“行政前台快递管理为什么这么难”…

办公环境监测与智能控制软硬件全套解决方案

心理学研究表明&#xff0c;良好的工作环境对员工的身心健康及提高工作效率有积极影响。 不仅如此&#xff0c;近几年国家尤其提倡“碳中和”与“碳达峰”政策&#xff0c;并提出“节约能源、美化环境”的重要目标。以“企业数字化转型”为根本&#xff0c;一切事物都在朝着智能…

因子图优化

最大后验概率估计问题 我们常将状态估计问题建模为最大后验估计&#xff08;MAP&#xff09;。之所以命名为最大后验估计&#xff0c;是因为它在给定了观测 Z \bm Z Z的情况下&#xff0c;最大化状态 X \bm X X的后验概率密度 p ( X ∣ Z ) p(\bm X|\bm Z) p(X∣Z) X M A P …