本文主要讲解如何正确使用 ViewData与ViewBag,以及他们之间的使用场景。首先需要知道,向视图中传递数据(从控制器中或者模型中)有两种类型: 强类型 弱类型

  • 强类型数据:viewmodel(安全,官方推荐)
  • 弱类型数据
    • ViewData ( ViewDataAttribute )
    • ViewBag

使用 viewmodel 将数据传递给视图可让视图充分利用强类型检查。 强类型化(或强类型)意味着每个变量和常量都有明确定义的类型(例如 string int DateTime )。 在编译时检查视图中使用的类型是否有效。

Visual Studio Visual Studio Code 列出了使用 IntelliSense 功能的强类型类成员。 如果要查看 viewmodel 的属性,请键入 viewmodel 的变量名称,后跟句点 ( . )。 这有助于提高编写代码的速度并降低错误率

可随意对 viewmodel 类型和业务模型类型使用相同的类。 但是,使用单独的模型可使视图独立于应用的业务逻辑和数据访问部分。 模型为用户发送给应用的数据使用 模型绑定 验证 时, 模型和 viewmodel 的分离也会提供安全优势

弱类型数据

除了强类型视图,视图还可以访问弱类型(也称为松散类型)的数据集合。 与强类型不同,弱类型(或松散类型)意味着不显式声明要使用的数据类型。 可以使用弱类型数据集合将少量数据传入及传出控制器和视图。

传递数据于... 示例
控制器和视图 用数据填充下拉列表。
视图和 布局视图 从视图文件设置布局视图中的 < title>元素内容。
分部视图 和视图 基于用户请求的网页显示数据的小组件

可以通过控制器和视图上的 ViewData ViewBag 属性来引用此集合。 ViewData 属性是弱类型对象的字典。 ViewBag 属性是 ViewData 的包装器,为基础 ViewData 集合提供动态属性。 注意:对于 ViewData ViewBag ,键查找都不区分大小写。

ViewData ViewBag 在运行时进行动态解析。 由于它们不提供编译时类型检查,因此使用这两者通常比使用 viewmodel 更容易出错。 出于上述原因,一些开发者希望尽量减少或根本不使用 ViewData ViewBag

ViewData

ViewData 是通过 string 键访问的 ViewDataDictionary 对象。 字符串数据可以直接存储和使用,而不需要强制转换 ,但是在提取其他 ViewData 对象值时必须将其强制转换为特定类型。 可以使用 ViewData 将数据从控制器传递到视图,以及在视图(包括 分部视图 布局 )内传递数据。

以下是在操作中使用 ViewData 设置问候语和地址值的示例:

public IActionResult SomeAction()
    ViewData["Greeting"] = "Hello";
    ViewData["Address"]  = new Address()
        Name = "Steve",
        Street = "123 Main St",
        City = "Hudson",
        State = "OH",
        PostalCode = "44236"
    return View();

在视图中处理数据

// Since Address isn't a string, it requires a cast. var address = ViewData["Address"] as Address; @ViewData["Greeting"] World! <address> @address.Name<br> @address.Street<br> @address.City, @address.State @address.PostalCode </address>

ViewData 特性

另一种会使用 ViewDataDictionary 的方法是 ViewDataAttribute 。 控制器或 Razor 页面模型上使用 [ViewData] 属性的属性将其值存储在字典中并从中进行加载。

在下面的示例中,“主页”控制器包含使用 [ViewData] 标记的 Title 属性。 About 方法设置“关于”视图的标题:

public class HomeController : Controller
    [ViewData]
    public string Title { get; set; }
    public IActionResult About()
        Title = "About Us";
        ViewData["Message"] = "Your application description page.";
        return View();

在“关于”视图中,以模型属性的形式访问 Title 属性:

<h1>@Model.Title</h1>

在布局中,从 ViewData 字典读取标题:

<!DOCTYPE html>
<html lang="en">
    <title>@ViewData["Title"] - WebApplication</title>

ViewBag

ViewBag在 Razor Pages 中不可用。

ViewBag 是 DynamicViewData 对象,可提供对存储在 ViewData 中的对象的动态访问。 ViewBag 不需要强制转换,因此使用起来更加方便。 下例演示如何使用与上述 ViewData 有相同结果的 ViewBag

public IActionResult SomeAction()
    ViewBag.Greeting = "Hello";
    ViewBag.Address  = new Address()
        Name = "Steve",
        Street = "123 Main St",
        City = "Hudson",
        State = "OH",
        PostalCode = "44236"
    return View();
@ViewBag.Greeting World!
<address>
    @ViewBag.Address.Name<br>
    @ViewBag.Address.Street<br>
    @ViewBag.Address.City, @ViewBag.Address.State @ViewBag.Address.PostalCode
</address>

同时使用 ViewData 和 ViewBag

ViewBag在 Razor Pages 中不可用。

由于 ViewData 和 ViewBag 引用相同的基础 ViewData 集合,因此在读取和写入值时,可以同时使用 ViewData 和 ViewBag,并在两者之间进行混合和匹配。

在 About.cshtml 视图顶部,使用 ViewBag 设置标题并使用 ViewData 设置说明

Layout = "/Views/Shared/_Layout.cshtml"; ViewBag.Title = "About Contoso"; ViewData["Description"] = "Let us tell you about Contoso's philosophy and mission.";

读取属性,但反向使用 ViewData 和 ViewBag。 在 _Layout.cshtml 文件中,使用 ViewData 获取标题并使用 ViewBag 获取说明

<!DOCTYPE html>
<html lang="en">
    <title>@ViewData["Title"]</title>
    <meta name="description" content="@ViewBag.Description">

请记住,字符串不需要为 ViewData 进行强制转换。 可以使用 @ViewData["Title"] 而不需要强制转换。

可同时使用 ViewData 和 ViewBag也可混合和匹配读取及写入属性。 呈现以下标记:

<!DOCTYPE html>
<html lang="en">
    <title>About Contoso</title>
    <meta name="description" content="Let us tell you about Contoso's philosophy and mission.">

ViewBag 在 Razor 页中不可用。

  • ViewData
    • 派生自 ViewDataDictionary,因此它有可用的字典属性,如 ContainsKeyAddRemove 和 Clear
    • 字典中的键是字符串,因此允许有空格。 예: ViewData["Some Key With Whitespace"]
    • 任何非 string 类型均须在视图中进行强制转换才能使用 ViewData
  • ViewBag
    • 派生自 DynamicViewData,因此它可使用点表示法 (@ViewBag.SomeKey = <value or object>) 创建动态属性,且无需强制转换。 ViewBag 的语法使添加到控制器和视图的速度更快。(其实差不多)
    • 更易于检查 NULL 值。 예: @ViewBag.Person?.Name

何时使用 ViewData 或 ViewBag

ViewData 和 ViewBag 都是在控制器和视图之间传递少量数据的有效方法。 根据偏好选择使用哪种方法。 可以混合和匹配 ViewData 和 ViewBag 对象,但是,使用一致的方法可以更轻松地读取和维护代码。 这两种方法都是在运行时进行动态解析的,因此容易造成运行时错误。 因而,一些开发团队会避免使用它们。

在控制器和视图之间传递少量数据时,比如排序时的排序字符串,可使用ViewData 。一些简单的处理逻辑用弱类型还是方便的

参考文献:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/views/overview?view=aspnetcore-2.2

前言本文主要讲解如何正确使用 ViewData与ViewBag,以及他们之间的使用场景。首先需要知道,向视图中传递数据(从控制器中或者模型中)有两种类型:强类型与弱类型。强类型数据:viewmodel(安全,官方推荐) 弱类型数据 ViewData(ViewDataAttribute) ViewBag 使用 viewmodel 将数据传递给视图可让视图充分利用强类型检查...
本文分析了.NET MVCViewData,ViewBag和TempData的区别。分享给大家供大家参考。具体分析如下: ViewData和TempData是字典类型,赋值方式用字典方式,如: 代码如下:ViewData[“myName”] ViewBag是动态类型,使用时直接添加属性赋值即可,如: 代码如下:ViewBag.myName ViewBagViewData只在当前Action有效,等同于View TempData可以通过转向继续使用,因为它的值保存在Session。但TempData只能经过一次传递,之后会被系统自动清除 ViewDataViewBag 的值可以互相访
1.用viewdata[“title”]显示网页标题,但是查看源代码显示的是类似;后厨信这样的 解决办法如下 &lt;title&gt;@Html.Raw(ViewData["Title"])&lt;/title&gt; &lt;meta name="keywords" content="@Html.Raw(ViewData["KeyWords"])" /&gt;
看过前两篇的朋友想必对Model绑定有个大概的了解,然而MVC框架给我们提供了更高的可扩展性的提供程序编程模式,也就是本篇的主题了,会讲解一下Model绑定器提供程序的实现以及解决一下上篇遗留的问题。 第一个问题是ModelBinderProviderCollection类型的执行过程? 还有个本篇的问题就是同样的向系统上下文注册Model绑定器和Model绑定器提供程序,哪一个优先级更高?
ViewBag.Message = “Your application description page.”; List colors = new List(); colors.Add(“Red”); colors.Add(“blue”); ViewBag.Listcolors = colors; return View(); ViewBag.Title = “About”; @View
本系列文章基于ASP.NET MVC Preview5. viewMVC模式与用户进行最直接的接触,它负责数据的呈现。这里要注意一点就是,view只是负责数据的呈现,所以我们应该要尽量让view不涉及业务逻辑的处理。 我们来添加一个Blog首页的view。在安装了ASP.NET MVC后,我们在添加新项目的时候可以看到有MVCview模板: 注:如果你的是文版的VS,安装完后可能...
之所以要谈及var和dynamic,是因为在使用EF框架和使用MVC的时候,会很频繁的用到他们,所以不得不提他们,以便在接触EF和MVC的时候能够很好的理解和熟练的应用. 先简单说一下var,虽被称作是可变类型,但他并不是一种若类型,只不过他是通过程序推断来确定类型的. 我们可以这么写:   static void Main(string[] args)
asp.net core获取ViewData值,即将ViewData值传给javascript变量 public IActionResult Index(Guid id) ViewData["ChannelID"] = id; return View(); $(function () { Channel
什么是强类型,什么是类型?哪种更好些?为什么? 强类型是在编译的时候就确定类型数据,在执行时类型不能更改,而类型在执行的时候才会确定类型。没有好不好,二者各有好处,强类型安全,因为它事先已经确定好了,而且效率高。一般用于编译型编程语言,如c++,java,c#,pascal等,类型相比而言不安全,在运行的时候容易出现错误,但它灵活,多用于解释型编程语言,如javascript等
1.视图组件介绍 视图组件是 ASP.NET Core MVC 的新特性,类似于局部视图,但它更强大。视图组件不使用模型绑定,并且仅依赖于调用它时所提供的数据视图组件特点: 呈块状,而不是整个响应 包括在控制器和视图之间发现的相同的关注点和可测试性优点 可以拥有参数和业务逻辑 通常从布局页面调用 视图组件可以用在任何需要重复逻辑且对局部视图来说过于复杂的情况,例如: 动态导航菜单 标签云(需要查询数据库) 最近发表的文章 典型博客上的侧边栏内容 将在每个页面上呈现的登录面板,根据
要实现任务排序,可以使用ASP.NET Core MVC框架的排序功能。在控制器,可以定义一个Action来处理排序请求,该Action可以接收排序参数并对任务进行排序。 例如,假设你有一个Task类,其包含一个Name和一个Priority属性。你可以定义一个Index Action来显示所有任务,并使用SortOrder参数来确定如何排序它们。 ```csharp public IActionResult Index(string sortOrder) ViewData["NameSortParm"] = sortOrder == "name" ? "name_desc" : "name"; ViewData["PrioritySortParm"] = sortOrder == "priority" ? "priority_desc" : "priority"; var tasks = from t in _context.Tasks select t; switch (sortOrder) case "name": tasks = tasks.OrderBy(t => t.Name); break; case "name_desc": tasks = tasks.OrderByDescending(t => t.Name); break; case "priority": tasks = tasks.OrderBy(t => t.Priority); break; case "priority_desc": tasks = tasks.OrderByDescending(t => t.Priority); break; default: tasks = tasks.OrderBy(t => t.Priority); break; return View(tasks.ToList()); 在这个例子,我们定义了两个视图数据项,用于在视图显示排序链接。我们使用LINQ查询来获取所有任务,并根据SortOrder参数对它们进行排序。最后,我们将排序后的任务列表传递给视图进行显示。 在视图,你可以使用Html.ActionLink来创建排序链接。例如,以下代码会创建一个名称排序链接: ```html @Html.ActionLink("Name", "Index", new { sortOrder = ViewBag.NameSortParm }) 这样,当用户单击这个链接时,会发送一个带有名称排序参数的请求,控制器会接收该请求并按名称排序任务列表。