zoukankan      html  css  js  c++  java
  • dotNET5的MVC页面传值方式总结

    本文大致讲解mvc前后端的传值方式,包括control向view、view向control、以及action向action。

    一.经典回顾

    我们回顾下在ASP.NET WebForms中,页面之间最常用的传值方式,有以下几种:

    • a). QueryString(也叫URL传值)
    • b). Session
    • c). Cookie
    • d). Application
    • e). Server.Transfer

    这里不再讲述这几种传值方式的用法和利弊,在本章后面将用MVC的传值方式与之对比,并展开一些探讨。(webform传值请看其他章节)

    二、Controller向View传值

    可以通过viewbag、viewdata、TempData、model。

    1. ViewBag

    1.png
    用法:
    在Controller中书写

    ViewBag.Test123 = "Hello World.";
    

    前台接收

    @ViewBag.Test123
    

    说明: ViewBag是dynamic动态类型,上面例子中的key => Test123可以指定任何类型

    2. ViewData

    2.png

    用法:

    在Controller中书写

    ViewData["Test123"] = "Hello World. This is ViewData";
    

    前台接收

    @ViewData["Test123"]
    

    说明:ViewData是字典类型,继承自IDictionary<string,object>接口

    3. TempData

    3.png

    用法:

    在Controller中书写

    TempData["tmpData"] = "I am TempData...";
    

    前台接收

    @TempData["tmpData"]
    

    说明:TempData也是字典类型,继承自IDictionary<string,object>接口

    4. Model

    这是初学者最常使用的传值方式。在上一篇文章中, 我们在Razor视图的页面代码中有这样一句:

    @model IEnumerable<MVC5Demo.Models.UserInfoViewModel>
    

    然后我们的信息列表是这样:

    <tbody>
        @foreach (var item in Model) { 
        <tr>
            <td>@Html.DisplayFor(p => item.UserName)</td>
            <td>@(item.Sex == 0 ? "女" : "男")</td>
            <td>@Html.DisplayFor(p => item.Age)</td>
            <td>@Html.DisplayFor(p => item.Dept)</td>
            <td>@Html.ActionLink("编辑", "Edit", "UserInfo", new { id=item.UserID.ToString() },null) @Html.ActionLink("删除", "Delete", "UserInfo", new { id = item.UserID.ToString() }, new { onclick="return confirm('确认删除"+item.UserName+"的记录?');" })</td>
        </tr>
        }
    </tbody>
    

    如代码所示,因为我们的Model是一个泛型集合,这里就可以很方便的取出集合中的数据。

    在后台Controller中,是怎么书写的呢?

    public ActionResult Index()
            {
                return View("UserInfo", GetTestData());//GetTestData()返回泛型集合
            }
    

    如代码所示,只需返回视图时,同时指定视图的数据对象。

    三、View向Controller传值

    1. 使用Html.BeginForm(...)方法提交表单

    @using(Html.BeginForm("actionName","controllerName"))
        {
            <div>表单内容</div>
            <div>...</div>
            <input type="submit" value="提交表单" />
        }
    

    说明:将

    开始标记写入响应。在用户提交窗体时,将由某个操作方法(指定Controller的某个Action)处理该请求。

    (使用using关闭form,下面不再说明。)

    2. 使用Html.BeginRouteForm(...)方法提交表单

    @Html.BeginRouteForm("路由名称", new { controller = "userinfo", action="save", userID = Model.UserID, userName = Model.UserName }, FormMethod.Post)
        {
            <div>表单内容</div>
            <div>...</div>
            <input type="submit" value="提交表单" />
        }
    

    说明:同Html.BeginForm(),但使用路由方式提交表单,同时参数也不同。

    3. 传统Form表单的Action属性提交

    <form id="postForm" action="@Url.Action("Save")" method="post">
                <div>表单内容</div>
                <div>...</div>
                <input type="submit" value="提交表单" />
        </form>
    

    说明:使用传统html form原生标记。

    4. 使用Ajax方式提交表单, Ajax.BeginForm(...)

    @Ajax.BeginForm("actionName", new AjaxOptions { Url="",OnSuccess="",HttpMethod="get" })
        {
            <div>表单内容</div>
            <div>...</div>
            <input type="submit" value="提交表单" />
        }
    

    说明:使用异步方式提交form表单。

    5. Jquery和Ajax提交表单

    省略... 不在文章讨论范围。

    6. 表单参数传递

    6.1 全参数传递

    [HttpPost]
    public ActionResult Save(string username,int sex,int age,string dept)
    

    说明:html标签name和参数名需相同。

    6.2 实体传参

    [HttpPost]
    public ActionResult Save(UserInfoViewModel item)
    

    说明:页面使用@model绑定类型

    6.3 表单集合传参

    [HttpPost]
    public ActionResult Save(FormCollection fc)
    

    说明:需解析FormCollection,如:

    UserInfoViewModel userInfo = new UserInfoViewModel();
    TryUpdateModel<UserInfoViewModel>(userInfo, fc);
    

    6.4 传统方式

    使用HttpContext,在MVC中我们同样可以使用以下对象:

    Application,Server,Session,Request,Response,Cache ...
    

    四、Controller向Controller传值(Action之间传值)

    1. RedirectToAction

    1.1 传递实体对象

    public ActionResult Index()
            {
                return RedirectToAction("Index", "Home", new UserInfoViewModel { UserID = Guid.NewGuid(), UserName = "zhangsan", Sex = 1, Age = 20, Dept = "hr" });
            }
    

    说明:在UserInfoController中,在页面加载时,新建一个实体类型,并跳转至首页。

    接收:

    public class HomeController : Controller
        {
            public ActionResult Index(UserInfoViewModel model)
            {
                //处理model的值
                //...
    

    1.2 传递普通参数

    public ActionResult Index()
            {
                return RedirectToAction("Index", "Home", new { UserID = Guid.NewGuid(), UserName = "zhangsan"});
            }
    

    接收:

    public class HomeController : Controller
        {
            public ActionResult Index(string userID,string userName)
            {
                //处理userID, userName的值
                //...
    
    1. TempData
    TempData["userName"] = "zhangsan";
                return RedirectToAction("Index2");
    

    在Index2中接收:

    string userName = TempData["userName"].ToString();

    说明:TempData可以在同Controller中不同Action之间传递,并且具有‘一次访问’的特质。使用时要特别注意。
    

    五、与WebForms传值的对比

    1. 后台不能通过非提交方式获取某个页面元素的值,因为没有‘服务器控件’;MVC使用原生Http,是【无状态】的。

    2. 不能使用(也没有)ViewState。

    3. 使用特有的机制传值(ViewData,ViewBag...等等)。

    六、MVC 向页面传值方式总结

    总结发现ASP.NET MVC中Controller向View传值的方式共有6种,分别是:

    • ViewBag
    • ViewData
    • TempData
    • 向普通View页面传一个Model对象
    • 向强类型页面传传一个Model对象
    • 用一个ViewModel对象解决所有问题

    首先我们需要明确的是我们从controller向view传值的时候,这些方式分别处于什么样的地位:

    我们一般会向页面传递一个主要的类型的数据,一般是情况下是一个List,如果只有这个,很好办,一个model对象就解决了,但是往往除此之外还会有一些额外的零散的数据需要传递,比如分页的pageIndex,或者pageCount等等,这样的数据用原有的model就无能为力了,这时候,我们就可以用ViewBag、ViewData、TempData来传递这些额外的数据。

    视图数据可以通过ViewBag属性访问,它主要是为了从Controller到view进行传值用的,类似有所使用的ViewData[] 字典类。对于ViewBag是如此的强大,意味着你能动态的set/get 值,增加任何数量的的额外字段而不需要强类型的检测。如:

    control控制器

    public 
    ActionResult Index()
    
    {
    
    List<string>
     colors = new 
    List<string>();
    
    colors.Add("red");
    
    colors.Add("green");
    
    colors.Add("blue");
    
    
    
    
    ViewData["listColors"]
     = colors;
    
    ViewData["dateNow"]
     = DateTime.Now;
    
    ViewData["name"]
     = "Hajan";
    
    ViewData["age"]
     = 25;
    
    
    
    return 
    View();
    

    control 控制器

    public 
    ActionResult Index()
    
    {
    
    List<string>
     colors = new 
    List<string>();
    
    colors.Add("red");
    
    colors.Add("green");
    
    colors.Add("blue");
    
    
    
    ViewBag.ListColors = colors;
    //colors
     is List
    
    ViewBag.DateNow
     = DateTime.Now;
    
    ViewBag.Name
     = "Hajan";
    
    ViewBag.Age
     = 25;
    
    return 
    View(); 
    
    }
    

    你和上面的对比 你看见了不同吗?

    View
    对应前台视图:

    1.使用ViewData

    <p>
    My name is <b>@ViewData["name"] </b>,
    <b>
    <br />
    I like the following colors:
    </p>
    <ul id="colors">
    @foreach (var color in ViewData["listColors"] as List<string>)
    {
    <li><font color="@color">@color </font></li>
    }
    </ul>
    <p>
    @ViewData["dateNow"]
    </p>
    

    2.使用ViewBag

    <p>
    My name is < b>@ViewBag.Name</b>, <b>@ViewBag.Age</b> years old.
    <br />
    I like the following colors:
    </p>
    <ul id="colors">
    @foreach (var color in ViewBag.ListColors)
    {
    <li><font color="@color">@color</font> </li>
    }
    </ul>
    <p>
    @ViewBag.DateNow
    </p>
    

    ViewBag、ViewData 和 TempData 的区别:

    ViewData 和 TempData 都可以传递弱类型数据,区别如下:

    • ViewData 只在当前 Action 中有效,生命周期和 View 相同;
    • TempData 的数据至多只能经过一次Controller传递,并且每个元素至多只能被访问一次,访问以后,自动被删除。
      -TempData 一般用于临时的缓存内容或抛出错误页面时传递错误信息,可以将TempData 在使用之前存储到相应的 ViewData 中以备循环使用。

    ViewBag

    我们可以认为 ViewBag=ViewData+Dynamic wrapper around the ViewData ,接下来你就可以体会到这个公式的含义了。

    1、conroller向view传值
    4.png

    2、view向view传值:

    5.png

    3、利用ViewBag传递一个对象:

    6.png

    ViewData

    1、ViewData的基本用法

    111.png

    2、ViewData 转换成 ViewBag:

    222.png

    3、ViewBag 转换成 ViewData:

    333.png

    TempData

    TempData用于在Redirect的时候保存数据,ViewData、ViewBag在跳转后就会变成null,但是TempData不会,下面是TempData的用法示例:

    public ActionResult Index()
    {
      var model = new Review()
                {
                    Body = "Start",
                    Rating=5
                };
        TempData["ModelName"] = model;
        return RedirectToAction("About");
    }
    <pre><pre lang="cs">public ActionResult About()
    {
        var model= TempData["ModelName"];
        return View(model);
    }
    

    普通页面传递model:

    //Action代码
    public ActionResult Index()
    {
      Product p = new Product();
      p.Name = "Toy";
      return View(p);
    }
    

    在View中调用的代码:

    Product : <%: ((Product)Model).Name %>
    

    向强类型试图传递model

    1、WebForm Engine的试图的实现:

    //Aciton的代码
    public ActionResult Index()
    {
      Product p = new Product();
      p.Name = "Toy";
      return View(p);
    }
    
    

    View中的代码
    声明类型

    <%@ Page Inherits="System.Web.Mvc.ViewPage<Product>" %>
    

    直接用Model调用该对象

    <h2> Product Name: <%: Model.Name %> </h2>
    

    2、Razor Engine的实现:

    在Razor中声明类型的方式:

    @model Mvc3App.Models.Product
    

    在Razor中调用对象的方式:

    <h2> Product: @Model.Name </h2>
    
  • 相关阅读:
    从 QSplitter 中移除 QWidget(使用隐藏与显示,切换十分方便,不要真正销毁)
    Qt虽然自己的源代码里不使用Exception,但也提供了一个QException及其子类QUnhandledException
    细说new与malloc的10点区别
    垃圾回收算法
    服务追踪数据使用 RabbitMQ 进行采集 + 数据存储使用 Elasticsearch + 数据展示使用 Kibana
    缓存穿透、缓存击穿与缓存雪崩
    微服务介绍
    分库分表
    Spring Boot、微服务架构和大数据
    Linux基本的操作
  • 原文地址:https://www.cnblogs.com/zoomla/p/14515599.html
Copyright © 2011-2022 走看看