zoukankan      html  css  js  c++  java
  • MVC 中的Model对象

          最近实在是太忙,客户丢了一个框架,没有任何说明文档,更没有所谓的技术支持,一直忙于学习,最后好歹还有点头绪,话不多说,MVC的学习是不能拉下的,就当前小白的我,认为MVC中的M并不是想象中的那样简单,一般用作前后台的数据交互。

    什么是模型?什么是模型绑定?

    微软出的《ASP.NET MVC 5编程实战》中有讲到,模型分领域模型、视图模型。个人理解视图模型就是一个数据库对应的实体类。领域模型狭义的来说包括视图模型和一些其他的属性。

           视图传递参数+值(或实体对象),Action中接收。看似是一瞬间完成的。中间其实是需要经过两个步骤,①通过实现IValueProvider接口来获取视图中(Form、RouteData、QueryString、HttpFileCollection)请求值。②在通过实现IModelBind中的方法将这些获取的请求参数、值绑定到Action中对应的形参上。同样这里接口中方法都是默认去调用的,如果有需要,可以进行自定义编写实现其接口的方法。

    比如,最常见的 将数据库中A表的部分数据显示在视图V中,然后进行增删该查操作。这里在视图V中,最上面会引用 该表的实体类@model  项目名.文件夹.实体类,再根据Razor语法,就可以用Lambda表达式点出来 该表的列名

    创建--前台表单数据提交到Controller

    @model MVC_plug.Models.Students
    @{
        ViewBag.Title = "Create";
    }
    <h2>Create</h2>
    @using (Html.BeginForm()) {
        @Html.ValidationSummary(true)
    
        <fieldset>
            <legend>Students</legend>  
            <div class="editor-label">
                @Html.LabelFor(model => model.Stu_Name)
            </div>
            <div class="editor-field">
                @Html.EditorFor(model => model.Stu_Name)
                @Html.ValidationMessageFor(model => model.Stu_Name)
            </div>

    这里 浏览器解析Razor 语法是 将 BeginForm 解析为From表单,对于HTML来说是,是不存在实体类之说的,表单提交的值仅仅是以键值对的方式进行存储后提交到指定的Action中.也就是将视图中的请求参数与action中的形参进行匹配、绑定。这就是简单模型绑定。

    1 .在Controller中对应的Action的方法体中 将 Student 作为参数来接收

            [HttpPost]
            public ActionResult Create(Students students)
            {
                if (ModelState.IsValid)
                {
                    db.Students.Add(students);
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
    
                return View(students);
            }

    既然View中不存在将提交的内容绑定到 实体类中,那么输入的数据为什么在Action的参数Student中可以点出来? 实际上 View 中Post提交的数据 是以键值对的方式进行存储,然后映射到提交的Action中的 Student中,前提是 View中的键名(Name名字)必须要等于 实体类型的属性名,否则无法绑定     

    2.在Controller中对应的Action的方法体中直接设置参数来接收值 ()

     public ActionResult Create(string Stu_Name,string Tel,string phone)

    运行项目,其中Stu_Name、Tel 有值,phone 无值,当然这只是佐证,如果在前台的View 中设置的名字不一样,后台用Student去接收,同样也会得到空值。

    后台传递数据到前台

    1. 显示某数据列表 ,同样是后台Controller 将 查询的结果 赋值给一个实体类对象,用反射也好,反序也行,再 Return View(实体类); 

        前台最上面要引用 @model 指向实体类 来接收传递的数据,因为是同一个实体,直接映射到前台,最后View 中进行显示即可

    2. 当然还可以选择 ViewData 和ViewBag 在后台的Action中赋值,然后在View中接收,关于这两者的比较,这里简单的整理下

        ViewData 的 ViewDataDictionary 是一个特殊的字典类,当在控制器中使用 ViewData["CurrentTime"] = DateTime.Now; 其实是将这个值以键值对的形式进行存储

        ViewBag不再是字典的键值对结构,而是dynamic动态类型,它会在程序运行的时候动态解析

    MVC 高级编程中提高两者的区别

    ①只有当要访问的关键字是一个有效的C#标识符时,ViewBag 才起作用。 

    例如,如果在ViewData["Key With Spaces"]中存放一个值,那么就不能使用ViewBag访问。因为这样根本就无法通过编译。

    ②动态值不能作为一个参数传递给扩展方法。因为C#编译器为了选择正确的扩展方法,在编译时必须知道每一个参数的真正类型。如果其中任何一个参数是动态的,那么就不会通过编译。

    例如,这行代码就会编译失败:@Html.TextBox("name",ViewBag.Name)。要使这行代码通过编译有两种方法:第一是使用ViewData["Name"],第二是把ViewBag.Name值转换为一个具体的型:(string)ViewBag.Name 。

    说白了,ViewBag 就是在ViewData的升级版,两者只能在Action中起作用,当然,两者的数据是可以相互访问。ViewBag的底层是ViewData,所以当两者定义同一属性不同值的时候,视图中显示的值永远是ViewData所定义的值

            // GET: Test
            public ActionResult Index()
            {
                                      
                ViewBag.Name = "顓頊viewbag";
                ViewData["Name"] = "顓頊viewdata";
                return View();
            }

    前台视图中显示的值,均是  顓頊viewdata

        @Html.TextBox("Name",(string)ViewBag.Name)
        <br/>
        @Html.TextBox("Name",ViewData["Name"])

    此外当用 TextBoxFor +强类型视图时,若在控制器中给实体类赋值,视图中又用New{ Value=“” } 来赋值,则实体对象中的值将被覆盖。

            public ActionResult Index()
            {
    
                Test te = new Test();
                te.Name = "顓頊";
                TestViewModel testViewModel = new TestViewModel()
                {
                    test = te,
                    Tests = new List<Test>()
                };
                           
                ViewBag.Name = "顓頊viewbag";
                ViewData["Name"] = "顓頊viewdata";
    
                return View(testViewModel);
            }

    如下视图均显示颛顼viewdata(Value中首字母V需大写)

        @Html.TextBoxFor(m => m.test.Name,new { Value= ViewData["Name"]})
        <br />
        @Html.TextBoxFor(m => m.test.Name, new { Value = (string)ViewBag.Name })

    市人皆大笑,举手揶揄之

  • 相关阅读:
    dotnet 新项目格式与对应框架预定义的宏
    dotnet 线程静态字段
    dotnet 线程静态字段
    dotnet 通过 WMI 拿到显卡信息
    dotnet 通过 WMI 拿到显卡信息
    dotnet 通过 WMI 获取指定进程的输入命令行
    dotnet 通过 WMI 获取指定进程的输入命令行
    dotnet 通过 WMI 获取系统信息
    dotnet 通过 WMI 获取系统信息
    PHP show_source() 函数
  • 原文地址:https://www.cnblogs.com/Sientuo/p/6598633.html
Copyright © 2011-2022 走看看