zoukankan      html  css  js  c++  java
  • ASP.NET MVC (二)——ASP.NET MVC 数据传递

    一、Controller与 View之间的值传递

    1、View将从从Controller获得Model中的数据。

         Model是MVC中 表示业务数据的层。

    2、ViewData相当于数据字典,包含Controlle和View之间传递的所有数据。Controller会在该字典中添加新数据项,View从字典中读取数据。

    二、使用View数据

    1. 创建Model 类,在Model文件夹下新建Employee类

    2. 在Controller 中获取Model,在GetView 方法中创建Employee 对象

    3. 创建ViewData 并返回View,在ViewData中存储Employee 对象

     1:  ViewData["Employee"] = emp;
       2:  return View("MyView");

    4. 在View中显示Employee 数据,打开MyView.cshtml。从ViewData中获取Employee 数据

    1:  <div>
       2:      @{
       3:          WebApplication1.Models.Employee emp=(WebApplication1.Models.Employee)
       4:              ViewData["Employee"];
       5:      }
       6:   
       7:  <b>Employee Details </b><br />
       8:      Employee Name : @emp.FirstName@emp.LastName <br />
       9:      Employee Salary: @emp.Salary.ToString("C")
      10:  </div>

    三、关于View

    1. 写Razor代码带花括号和没有花括号有什么区别?

       1:  @{
       2:      c#代码
       3:  }
    
    

    @符号后没有花括号只是简单的显示变量或表达式的值

    2、

    2. 为什么需要强制转换类型

    ViewData可操作内部对象,每次添加新值,会封装成对象类型,因此每次都需要解压来提取值。

    3. @emp.FirstName @emp.LastName有什么特殊含义?

    意味着LastName显示在FirstName之后并自动添加空格。

    4. 为什么 Employee中的 硬编码是由Controller创建的 ?

    在本文中只是为了实现实验目的,因此采用硬编码,实际使用中,是从数据库或Web服务中获取的。

    5. 数据库逻辑,数据访问层,业务层分别指的是什么?

    • 数据访问层是ASP.NET MVC中是一直隐式存在的,MVC定义中不包含数据访问层的定义。
    • 业务层是解释器的先驱,是Model的一部分。

    完整的MVC结构

    四、ViewBag的使用

    ViewBag可以称为ViewData的一块关于语法的辅助的糖果,ViewBag使用C# 4.0的动态特征,使得ViewData也具有动态特性。

    ViewData与ViewBag对比:

    ViewData

    ViewBag

    它是Key/Value字典集合

    它是dynamic类型对像

    从Asp.net MVC 1 就有了

    ASP.NET MVC3 才有

    基于Asp.net 3.5 framework

    基于Asp.net 4.0与.net framework

    ViewData比ViewBag快

    ViewBag比ViewData慢

    在ViewPage中查询数据时需要转换合适的类型

    在ViewPage中查询数据时不需要类型转换

    有一些类型转换代码

    可读性更好

    ViewBag内部调用ViewData。

    1. 创建View Bag

    1:  ViewBag.Employee = emp;

    2. 在View中显示EmployeeData

    使用以下代码来替代实验三中第四步中的代码:

       1:  @{
       2:      WebApplication1.Models.Employee emp = (WebApplication1.Models.Employee)
       3:          ViewBag.Employee;
       4:  }
       5:  Employee Details
       6:   
       7:  Employee Name: @emp.FirstName @emp.LastName 
       8:   
       9:  Employee Salary: @emp.Salary.ToString("C")
    五、ViewData与ViewBag的问题
    1、可以传递ViewData,接收时获取ViewBag吗?

    答案是肯定的,反之亦然。如之前所说的,ViewBag只是ViewData的一块糖/

    2、ViewData和ViewBag 是Contoller与View之间值传递的内容。但是在实际使用的过程中,它们并不是最佳选择,接下来我们来看看使用它们的缺点:

    • 性能问题;ViewData中的值都是对象类型,使用之前必须强制转换为合适的类型。会添加额外的性能负担。
    • 没有类型安全就没有编译时错误,如果尝试将其转换为错误的类型,运行时会报错。良好的编程经验告诉我们,错误必须在编译时捕获。
    • 数据发送和数据接收之间没有正确的连接;MVC中,Controller和View是松散的连接的。Controller是无法捕获View变化,View也无法捕获到Controller内部发生的变化。从Controller传递一个ViewData或ViewBag的值,当开发人员正在View中写入,就必须记录从Controller中即将获得什么值。如果Controller与View开发人员不是相同的开发人员,开发工作会变得非常困难。会导致许多运行时问题,降低了开发效率。

    六、强类型View

    ViewModel 解决方法

    ViewModel是ASP.NET MVC应用中隐式声明的层。它是用于维护Model与View之间数据传递的,是View的数据容器。

    Model 和 ViewModel 的区别

    Model是业务相关数据,是根据业务和数据结构创建的。ViewModel是视图相关的数据。是根据View创建的。

    具体的工作原理

    1. Controller 处理用户交互逻辑或简单的判断。处理用户需求
    2. Controller 获取一个或多个Model数据
    3. Controller 决策哪个View最符合用户的请求
    4. Controller 将根据Model数据和View需求创建并且初始化ViewModel对象。
    5. Controller 将ViewModel数据以ViewData或ViewBag或强类型View等对象传递到View中。
    6. Controller 返回View。

    View 与 ViewModel 之间是如何关联的?

    View将变成ViewModel的强类型View。

    Model和 ViewModel 是如何关联的?

    Model和ViewModel 是互相独立的,Controller将根据Model对象创建并初始化ViewModel对象。

    接下来我们来看实验6:

    实验6—— 实现ViewModel

    1. 新建文件夹

    在项目中创建新文件夹并命名为ViewModels。

    2. 新建EmployeeViewModel

    为了达到实验目的,首先列出我们的实验需求:

    1. 名和姓应该合并显示。

    2. 使用货币显示数量

    3. 薪资以不同的颜色来显示

    4. 当前登录用户也需要在View中显示。

    在ViewModels类中,创建新类并命名为EmployeeViewModel,如下所示:

       1:  public class EmployeeViewModel
       2:  {
       3:      public string EmployeeName { get; set; }
       4:      public string Salary { get; set; }
       5:      public string SalaryColor { get; set; }
       6:      public string UserName{get;set;}
       7:  }
    注意,姓和名应该使用EmployeeName这一个属性。而Salary属性的数据类型是字符串,且有两个新的属性添加称为SalaryColor和UserName。
    3. View中使用ViewModel

    实验五中已经创建了View的强类型Employee。将它改为 EmployeeViewModel

       1:  @using WebApplication1.ViewModels
       2:  @model EmployeeViewModel
    
    

    4. 在View中显示数据

    使用以下脚本代替View部分的内容

       1:  Hello @Model.UserName
       2:  <hr />
       3:  <div>
       4:  <b>Employee Details</b><br />
       5:      Employee Name : @Model.EmployeeName <br />
       6:  <span style="
       7:          Employee Salary: @Model.Salary
       8:  </span>
       9:  </div>

    5. 新建并传递ViewModel

    在GetView方法中,获取Model数据并且将强制转换为ViewModel对象。

       1:  public ActionResult GetView()
       2:  {
       3:      Employee emp = new Employee();
       4:      emp.FirstName = "Sukesh";
       5:      emp.LastName="Marla";
       6:      emp.Salary = 20000;
       7:   
       8:      EmployeeViewModel vmEmp = new EmployeeViewModel();
       9:      vmEmp.EmployeeName = emp.FirstName + " " + emp.LastName;
      10:      vmEmp.Salary = emp.Salary.ToString("C");
      11:      if(emp.Salary>15000)
      12:      {
      13:          vmEmp.SalaryColor="yellow";
      14:      }
      15:      else
      16:      {
      17:          vmEmp.SalaryColor = "green";
      18:      }
      19:   
      20:  vmEmp.UserName = "Admin"
      21:   
      22:      return View("MyView", vmEmp);
      23:  }

    6. 测试输出

    clip_image006

    尽管运行结果类似,但是View中不包含任何业务逻辑。

    关于实验6

    是否意味着,每个Model都有一个ViewModel?

    每个View有其对应的ViewModel。

    Model与ViewModel之间存在关联是否是好的实现方法?

    最好的是Model与ViewModel之间相互独立。

    需要每次都创建ViewModel吗?假如View不包含任何呈现逻辑只显示Model数据的情况下还需要创建ViewModel吗?

    建议是每次都创建ViewModel,每个View都应该有对应的ViewModel,尽管ViewModel包含与Model中相同的属性。

    假定一个View不包含任何呈现逻辑,只显示Model数据,我们不创建ViewModel会发生什么?

    无法满足未来的需求,如果未来需要添加新数据,我们需要从头开始创建全新的UI,所以如果我们保持规定,从开始创建ViewModel,就不会发生这种情况。在本实例中,初始阶段的ViewModel将与Model几乎完全相同。

    实验7——带有集合的View

    在本实验中,在View中显示Employee列表。

    1. 修改EmployeeViewModel 类

    删除UserName属性

       1:  public class EmployeeViewModel
       2:  {
       3:      public string EmployeeName { get; set; }
       4:      public string Salary { get; set; }
       5:      public string SalaryColor { get; set; }
       6:  }

    2. 创建结合ViewModel

    在ViewModels 文件下,创建新类并命名为EmployeeListViewModel

       1:  public class EmployeeListViewModel
       2:  {
       3:      public List<employeeviewmodel> Employees { get; set; }
       4:  public string UserName { get; set; }
       5:  }
     

    3. 修改强类型View的类型

       1:  @using WebApplication1.ViewModels
       2:  @model EmployeeListViewModel

    4. 显示View中所有的Employee

       1:  <body>
       2:      Hello @Model.UserName
       3:  <hr />
       4:  <div>
       5:  <table>
       6:  <tr>
       7:  <th>Employee Name</th>
       8:  <th>Salary</th>
       9:  </tr>
      10:             @foreach (EmployeeViewModel item in Model.Employees)
      11:             {
      12:  <tr>
      13:  <td>@item.EmployeeName</td>
      14:  <td style="@item.Salary</td>
      15:  </tr>
      16:             }
      17:  </table>
      18:  </div>
      19:  </body>
    
    

    5. 创建Employee的业务逻辑

    新建类并命名为EmployeeBusinessLayer ,并带有GetEmployees()方法。

       1:  public class EmployeeBusinessLayer
       2:  {
       3:      public List<employee> GetEmployees()
       4:      {
       5:          List<employee> employees = new List<employee>();
       6:          Employee emp = new Employee();
       7:          emp.FirstName = "johnson";
       8:          emp.LastName = " fernandes";
       9:          emp.Salary = 14000;
      10:          employees.Add(emp);
      11:   
      12:          emp = new Employee();
      13:          emp.FirstName = "michael";
      14:          emp.LastName = "jackson";
      15:          emp.Salary = 16000;
      16:          employees.Add(emp);
      17:   
      18:          emp = new Employee();
      19:          emp.FirstName = "robert";
      20:          emp.LastName = " pattinson";
      21:          emp.Salary = 20000;
      22:          employees.Add(emp);
      23:   
      24:          return employees;
      25:      }
      26:  }
      27:  </employee>

    6.从控制器中传参

       1:  public ActionResult GetView()
       2:  {
       3:      EmployeeListViewModel employeeListViewModel = new EmployeeListViewModel();
       4:   
       5:      EmployeeBusinessLayer empBal = new EmployeeBusinessLayer();
       6:      List<employee> employees = empBal.GetEmployees();
       7:   
       8:      List<employeeviewmodel> empViewModels = new List<employeeviewmodel>();
       9:   
      10:      foreach (Employee emp in employees)
      11:      {
      12:          EmployeeViewModel empViewModel = new EmployeeViewModel();
      13:          empViewModel.EmployeeName = emp.FirstName + " " + emp.LastName;
      14:          empViewModel.Salary = emp.Salary.ToString("C");
      15:          if (emp.Salary > 15000)
      16:          {
      17:              empViewModel.SalaryColor = "yellow";
      18:          }
      19:          else
      20:          {
      21:              empViewModel.SalaryColor = "green";
      22:          }
      23:          empViewModels.Add(empViewModel);
      24:      }
      25:      employeeListViewModel.Employees = empViewModels;
      26:      employeeListViewModel.UserName = "Admin";
      27:      return View("MyView", employeeListViewModel);
      28:  }
      29:  </employeeviewmodel></employeeviewmodel></employee>

    7.  执行

    clip_image007

    关于实验7

    是否可以制定强类型View列表?

    是的 为什么要新建EmployeeListViewModel单独的类而不直接使用强类型View的列表?1.    策划未来会出现的呈现逻辑2.    UserName属性。UserName是与employees无关的属性,与完整View相关的属性。为什么删除EmployeeViewModel 的UserName属性,而不是将它作为EmployeeListViewModel的一部分?UserName 是相同的,不需要EmployeeViewModel中添加UserName。

  • 相关阅读:
    POJ 基本算法(3)
    给定范围的素数筛选(POJ 2689)
    无向图、有向图的最小环
    第k短路和A*
    HDU 4302 Holedox Eating (set + iterator)
    笛卡尔树
    HDU 多校联合第一场
    HDU 多校联合第二场
    POJ 图算法(3)
    POJ 1038 Bugs Integrated, Inc. (状态dp)
  • 原文地址:https://www.cnblogs.com/fengsantianya/p/5885868.html
Copyright © 2011-2022 走看看