ASP.NET MVC (二) 数据传递

摘要:七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递,Controller与 View之间的值传递在上一节的实验二中已经创建了静态View。然而在实际使用情况下,View常用于显示动态数据。在实验三中们将在View中动态显示数据。View将从从Controller获得Model中的数据。Model是MVC中 表示业务数据的层。实验3 &...

作者:LoveCode标签:七天学会ASP.NET,MVC,(二),ASP.NET,MVC,数据传递,数据,类型,微软,逻辑,对象,属性,代码,业务

Controller与 View之间的值传递

在上一节的实验二中已经创建了静态View。然而在实际使用情况下,View常用于显示动态数据。在实验三中们将在View中动态显示数据。

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

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

实验3 ——使用View数据

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

1. 创建Model

在Model文件夹下新建Employee类,如下。

 public class Employee
 {
     public string FirstName { get; set; }
     public string LastName { get; set; }
     public int Salary { get; set; }
 }


2. 在Controller 中获取Model

在GetView 方法中创建Employee 对象:

 Employee emp = new Employee();
 {
     emp.FirstName = "Sukesh";
     emp.LastName="Marla";
     emp.Salary = 20000;
 }

注意:请确保使用Using语句包含此类,或者使用类的全称。

using WebApplication1.Models;


3. 创建ViewData 并返回View

在ViewData中存储Employee 对象。

ViewData["Employee"] = emp;

return View("MyView");


4. 在View中显示Employee 数据

打开MyView.cshtml。

从ViewData中获取Employee 数据并按照如下代码显示:

 <div>
      @{
           WebApplication1.Models.Employee emp=(WebApplication1.Models.Employee)ViewData["Employee"];
      }
      
      <b>Employee Details </b><br />
      Employee Name : @emp.FirstName@emp.LastName <br />
      Employee Salary: @emp.Salary.ToString("C")
 </div>


5. 测试输出

按F5运行

clip_image001

关于实验 3

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

在实验三中@emp.FirstName能够使用以下脚本来代替

 @{ Response.Write(emp.FirstName); }

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


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

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


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

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


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

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


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

  • 数据访问层是ASP.NET MVC中是一直隐式存在的,MVC定义中不包含数据访问层的定义。

  • 业务层是解释器的先驱,是Model的一部分。

完整的MVC结构

clip_image003

实验4 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

在实验三的基础之上,使用以下脚本代替第三步中的代码。

ViewBag.Employee = emp;


2. 在View中显示EmployeeData

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

@{
    WebApplication1.Models.Employee emp = (WebApplication1.Models.Employee)ViewBag.Employee;
}

Employee Details
Employee Name: @emp.FirstName @emp.LastName 
Employee Salary: @emp.Salary.ToString("C")


3. 测试输出

运行结果:

clip_image001[1]

关于实验4

可以传递ViewData,接收时获取ViewBag吗?

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


ViewData与ViewBag的问题

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

  • 性能问题;ViewData中的值都是对象类型,使用之前必须强制转换为合适的类型。会添加额外的性能负担。

  • 没有类型安全就没有编译时错误,如果尝试将其转换为错误的类型,运行时会报错。良好的编程经验告诉我们,错误必须在编译时捕获。

  • 数据发送和数据接收之间没有正确的连接;MVC中,Controller和View是松散的连接的。Controller是无法捕获View变化,View也无法捕获到Controller内部发生的变化。从Controller传递一个ViewData或ViewBag的值,当开发人员正在View中写入,就必须记录从Controller中即将获得什么值。如果Controller与View开发人员不是相同的开发人员,开发工作会变得非常困难。会导致许多运行时问题,降低了开发效率。

实验5 理解强类型View

ViewData和ViewBag引起的所有问题根源都在于数据类型。参数值的数据类型是被封装在ViewData中的,称为对象。

如果能够设置Controller和View之间参数传递的数据类型,那么上述问题就会得到解决,因此从得出强类型View。

接下来,我们看一个简单的例子,如果工资大于15000则显示黄色,低于显示绿色。

1. 创建View的强类型

在View的顶部添加以下代码:

@model WebApplication1.Models.Employee


2. 显示数据

在View内部输入@Model.就会查看到Model类的属性

clip_image004

添加以下代码来显示数据:

 Employee Details
 Employee Name : @Model.FirstName @Model.LastName 
 
  @if(Model.Salary>15000)
  {
      <span style="background-color:yellow">
      Employee Salary: @Model.Salary.ToString("C")
      </span>
  }
 else
 { 
      <span style="background-color:green">
      Employee Salary: @Model.Salary.ToString("C")
      </span>
 }


3. 从Controller Action方法中传递Model数据。

修改action代码

 Employee emp = new Employee();
 emp.FirstName = "Sukesh";
 emp.LastName="Marla";
 emp.Salary = 20000; 
 
 return View("MyView",emp);


4. 测试输出

clip_image005

关于实验5

View中使用类时需要声明类的全称吗 (Namespace.ClassName)?

添加以下语句,就不需要添加全称。

 @using WebApplication1.Models
 @model Employee


是否必须设置强类型视图或不使用ViewData和ViewBag?

设置强类型视图是最佳解决方案。

是否能将View设置为多个Model使用的强类型?

不可以,实际项目中在一个View中想要显示多个Model时以点结束的。该问题的解决方法将在下一节讨论。

理解ASP.NET MVC 中的View Model

实验5中已经违反了MVC的基本准则。根据MVC,V是View纯UI,不包含任何逻辑层。而我们在实验5中以下三点违反了MVC的体系架构规则。

1. 附加姓和名显示全名&mdash;&mdash;逻辑层

2. 使用货币显示工资&mdash;&mdash;逻辑层

3. 使用不同的颜色表示工资值,使用简单的逻辑改变了HTML元素的外观。&mdash;&mdash;逻辑层

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&mdash;&mdash; 实现ViewModel

1. 新建文件夹

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

2. 新建EmployeeViewModel

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

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

2. 使用货币显示数量

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

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

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

 public class EmployeeViewModel
 {
      public string EmployeeName { get; set; }
      public string Salary { get; set; }
      public string SalaryColor { get; set; }
      public string UserName{get;set;}
 }
 //注意,姓和名应该使用EmployeeName这一个属性。而Salary属性的数据类型是字符串,且有两个新的属性添加称为SalaryColor和UserName。


3. View中使用ViewModel

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

 @using WebApplication1.ViewModels
 @model EmployeeViewModel


4. 在View中显示数据

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

  Hello @Model.UserName
  <hr />
  <div>
      <b>Employee Details</b><br />
      Employee Name : @Model.EmployeeName <br />
      <span style="background-color:@Model.SalaryColor">
      Employee Salary: @Model.Salary
  </span>
  </div>


5. 新建并传递ViewModel

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

public ActionResult GetView()
{
     Employee emp = new Employee();
     emp.FirstName = "Sukesh";
     emp.LastName="Marla";
     emp.Salary = 20000;
     EmployeeViewModel vmEmp = new EmployeeViewModel();
     vmEmp.EmployeeName = emp.FirstName + " " + emp.LastName;
     vmEmp.Salary = emp.Salary.ToString("C");
     
     if(emp.Salary>15000)
     {
         vmEmp.SalaryColor="yellow";
     }
     else
     {
         vmEmp.SalaryColor = "green";
     }
     vmEmp.UserName = "Admin"
     
      return View("MyView", vmEmp);
}


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&mdash;&mdash;带有集合的View

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

1. 修改EmployeeViewModel 类

删除UserName属性

 public class EmployeeViewModel
 {
     public string EmployeeName { get; set; }
      public string Salary { get; set; }
      public string SalaryColor { get; set; }
 }


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="background-color:@item.SalaryColor">@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.  执行

关于实验7

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

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

结论

以上就是我们第二天所讲的内容,在第三天我们会学习新内容!

移动时代,触控优先,使用 ComponentOne Studio Enterprise 中提供的 ComponentOne Studio ASP.NET MVC 版本,您能获取快速的轻量级控件来满足用户所有需求。

它与Visual Studio无缝集成,完全与MVC6和ASP.NET 5.0兼容,将大幅提高效率,能提供从桌面到移动设备的体验,不用任何妥协就能创建触控优先的现代化解决方案。

CopyRight © 2017 荒山本的官方网站 粤ICP备16049175号 All Right Service 网站地图(xml) 网站地图(html)