VS.NET MVC(一)

一. MVC简介
1.MVC是ASP.NET WebForm之外另一种WEB应用程序的开发方式.设计模式为Model-View-Controller.

1.1 Model 模型
操作资料或处理资料逻辑.
1.2 View  视图
用户介面.
1.3 Controllerr 控制器
控制应用程序流程,并指定要呈现的View或存取哪个Model.

2. MVC架构的主要优点

2.1 主要分为M-V-C三个部分,使用项目更方便管理与维护.
2.2 MVC不使用ViewState和服务器控件,所以执行速度较快,所耗费的流量也相对小.
2.3 支持测试导向开发工作,要同时建立测试方案,为单元的每一个动作生成测试代码进行测试工作.
3.MVC的运行模式
3.1 用户通过浏览器发送请求(Request)
3.2 应用服务器收到请求后,与MVC的Rounting进行比对,执行对应的控制器(Controller)的动作(Action).
3.3 控制器通过Model存取数据.
3.4 控制器将结果传递给指定的View并呈现给用户.

在这里插入图片描述

二. 建立一个CRUD的MVC例子

  1. 新建项目
    在这里插入图片描述

  2. 加入数据库及表
    2.1 在APP_Data 目录右击加入新项目SQL Server Database

在这里插入图片描述

 文件在APP_Data目录下

在这里插入图片描述

甲、 右击[Tables]增加新表[Update]
在这里插入图片描述

  1. 通过ENTITY FRAMEWORK 加入模型
    右击Models加入新项目ADO.NET Entity Data ModelEF Designer from database加入对应的表\项目\存储过程

在这里插入图片描述

  1. 数据读取,建立控件器Controller,增加新增,查询列表,修改,删除Action.
// GET: Home (查询列表,带分页控件PagedList.)
        public ActionResult Index(int page =1)
        {
            int pagesize = 3;
            int pagecur = page < 1 ? 1 : page;                 
            var tToDo = dbentity.tToDoes.OrderByDescending(o => o.fDate).ToList().ToPagedList(pagecur,pagesize);
            return View(tToDo);             
        }
//-------新增 的代码开始
//显示新增的页面-------------------------------------
        public ActionResult Create()
        {
            return View();
        }
        [HttpPost]           //注:参数变量的名称与前端控件的名称一致,会自动对应.
        public ActionResult Create(String fTitle, string fImage, DateTime fDate)
        {
            tToDo todo = new tToDo();
            todo.fTitle = fTitle;
            todo.fImage = fImage;
            todo.fDate = fDate;
            dbentity.tToDoes.Add(todo);
            dbentity.SaveChanges();
            return RedirectToAction("Index");
        }
        [HttpPost]            //前端的控件为 @Html.EditFor (Model的属性名),会自动对应.
        public ActionResult Create(tToDo todo)
        {
            dbentity.tToDoes.Add(todo);
            dbentity.SaveChanges();
            return RedirectToAction("Index");
        }
        [HttpGet]        //用Ajax Get 的方式把数据从前端传过来.
        public string CreateInAjax(string data)
        {
            try
            {
                dynamic obj = JsonConvert.DeserializeObject<dynamic>(data);
                tToDo todo = new tToDo();
                todo.fTitle = obj.fTitle;
                todo.fImage = obj.fImage;
                todo.fDate = obj.fDate;
                dbentity.tToDoes.Add(todo);
                dbentity.SaveChanges();
                return "Save.";
            }
            catch
            {
                return "Fail to save.";
            }
           
        }
        [HttpPost]                       //用Ajax Post 的方式把数据从前端传过来.
        public string CreateInAjaxPost(string data)
        {                                    
            try
            {
                dynamic obj = JsonConvert.DeserializeObject<dynamic>(data);
                tToDo todo = new tToDo();
                todo.fTitle = obj.fTitle;
                todo.fImage = obj.fImage;
                todo.fDate = obj.fDate;
                dbentity.tToDoes.Add(todo);
                dbentity.SaveChanges();
                return "Save.";
            }
            catch
            {
                return "Fail to save.";
            }
//-------新增 的代码结束 
//显示修改的页面
        public ActionResult Edit(int id)
        {
            var todo = dbentity.tToDoes.Where(o => o.Id == id).FirstOrDefault();
            return View(todo);
        }
        //保存修改
        [HttpPost]
        public ActionResult Edit(int id,string fTitle,string fImage,DateTime fDate)
        {
           var todo = dbentity.tToDoes.Where(o => o.Id == id).FirstOrDefault();
            todo.fTitle = fTitle;
            todo.fImage = fImage;
            todo.fDate = fDate;
            dbentity.SaveChanges();
            return RedirectToAction("Index");
}
//删除
     public ActionResult Delete(int id)
        {
            var todo = dbentity.tToDoes.Where(o => o.Id == id).FirstOrDefault();
            dbentity.tToDoes.Remove(todo);
            dbentity.SaveChanges();
            return RedirectToAction("Index");
        }
}
  1. 数据新增VIEW
@model prjMVC20210420.Models.tToDo

@{
    ViewBag.Title = "Create To do list";
}
<script>
    function SaveData() {       //Ajax Get  
        var data = '{ fTitle: "How to learn MVC", fImage: "1.png", fDate: "2025-05-06" }';
        $.ajax(
            {
                url: "http://localhost:63534/Home/CreateInAjax?data=" + data,
                type: 'GET',              
                success: function (data) {                   
                    alert(data);
                    location.href = "http://localhost:63534/Home/Index";
                }
            }
        );
    }
    function SaveDataPost() {  //Ajax Post   
        var data = 'data={ fTitle: "How to learn MVC", fImage: "1.png", fDate: "2025-05-06" }';
        $.ajax(
            {
                url: "http://localhost:63534/Home/CreateInAjaxPost",
                data:data,
                type: 'POST',
                dataType:'text',
                success: function (data) {
                    alert(data);
                    location.href = "http://localhost:63534/Home/Index";
                }
            }
        );
    }
</script>
<h2>Create to do list</h2>

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>tToDo</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
           <label class="control-label col-md-2">Title</label>
            <div class="col-md-10">
                @Html.EditorFor(model => model.fTitle, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.fTitle, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
           <label class="control-label col-md-2" >Image</label>
            <div class="col-md-10">
                <select id="fImage" name="fImage" class="form-control">
                    <option value="0.png">Important</option>
                    <option value="1.png">Common</option>
                </select>
            </div>
        </div>

        <div class="form-group">
          <label class="control-label col-md-2">Date</label>
            <div class="col-md-10">
                @Html.EditorFor(model => model.fDate, new { htmlAttributes = new { @class = "form-control"
                                                                                    ,type="date",required="required"} })
                @Html.ValidationMessageFor(model => model.fDate, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
                <input type="button" value="Ajax Submit" onclick="SaveDataPost();" class="btn btn-danger " />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
  1. 数据查询列表, 删除 VIEW
@using PagedList.Mvc; <!--引入分页控件-->
@using PagedList;
@model IPagedList<prjMVC20210420.Models.tToDo>

@{
    ViewBag.Title = "Index";
}
<link href="~/Content/PagedList.css" rel="stylesheet" />

<p>
    @Html.ActionLink("Create New", "Create")  <!--到新增页面-->
</p>
<table class="table">
    <tr>  <th>   Title </th>  <th>  Image  </th>  <th>   Date  </th> <th></th>  </tr>
    @foreach (var item in Model)
    {
        <tr>
            <td>
                @item.fTitle
            </td>
            <td>
                @item.fImage
            </td>
            <td>
                @item.fDate
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = @item.Id }) |
                @Html.ActionLink("Delete", "Delete", new { id = @item.Id })
            </td>
        </tr>
    }

</table>

@Html.PagedListPager(Model, page => Url.Action("Index", new { page })) <!--分页-->

7.数据修改VIEW

@model prjMVC20210420.Models.tToDo

@{
    ViewBag.Title = "Edit to do list";
}
<h2>Edit to do list</h2>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()    
    <div class="form-horizontal">      
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.Id)
        <div class="form-group">
          <label class="control-label col-md-2">Title</label>
            <div class="col-md-10">
                @Html.EditorFor(model => model.fTitle, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.fTitle, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2">Image</label>
            <div class="col-md-10">
           <select id="fImage" name="fImage" class="form-control">
               <option value="0.png" @(Model.fImage =="0.png" ? "selected" : "")>Important</option>
               <option value="1.png" @(Model.fImage=="1.png" ? "selected" : "")>Common</option>
           </select>               
            </div>
        </div>
        <div class="form-group">
            <label class="control-label col-md-2">Date</label>
            <div class="col-md-10">
                @Html.EditorFor(model => model.fDate, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.fDate, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>

三. 控制器 Controller介绍

控制器是MVC Web应用程序的核心内容之一. 一个控制器中包含多个公开(public)的动作(action),这些公开的动作对应于指定的url,透过这些动作与用户操作进行互动,对model资料进行逻辑处理后返回view给用户.

一个Controller的例子:

public class HomeController : Controller
    {
         DbEntities dbentity = new DbEntities();
        // GET: Home
        public ActionResult Index()
        {
            var tToDo = dbentity.tToDoes.OrderByDescending(o => o.fDate).ToList();
            return View(tToDo);
        }

        public ActionResult Create()
        {
            return View();
        }
        [HttpPost]
        public ActionResult Create(String fTitle, string fImage, DateTime fDate)
        {
            tToDo todo = new tToDo();
            todo.fTitle = fTitle;
            todo.fImage = fImage;
            todo.fDate = fDate;
            dbentity.tToDoes.Add(todo);
            dbentity.SaveChanges();
            return RedirectToAction("Index");
        }
      
        public ActionResult Delete(int id)
        {
            var todo = dbentity.tToDoes.Where(o => o.Id == id).FirstOrDefault();
            dbentity.tToDoes.Remove(todo);
            dbentity.SaveChanges();
            return RedirectToAction("Index");
        }
        public ActionResult Edit(int id)
        {
            var todo = dbentity.tToDoes.Where(o => o.Id == id).FirstOrDefault();
            return View(todo);
        }
        [HttpPost]
        public ActionResult Edit(int id,string fTitle,string fImage,DateTime fDate)
        {
           var todo = dbentity.tToDoes.Where(o => o.Id == id).FirstOrDefault();
            todo.fTitle = fTitle;
            todo.fImage = fImage;
            todo.fDate = fDate;
            dbentity.SaveChanges();
            RedirectToAction("Index");
        }
protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                dbentity.Dispose();
            }
            base.Dispose(disposing);
        }
    }

(一)注意控制器的写法: 
1. 控制器的类别必须是Public.
2. 控制器的名称必须是Controller结尾.例如HomeController…
3. 控制器类别必须继承Controller,或是实例化IController接口
4. Action方法必须是Public才能被前端呼叫执行,否则为一般方法.

(二)控制器主要负责:
1. 找出要执行的动作并验证执行;
2. 取得动作方法的参数;
3. 处理执行期间发生的错误;
4. 向用户返回view.
(三)action动作
1.常用action方法
例如:http://webname/Home/Index
对应HomeController的Index 方法
Public class HomeController:Controller
{
Public ActionResult Index()
{
……
}
}

也可以:
[ActionName(“Index”)]
Public ActionResult Show()
{

}

如果加入[NonAction],则会被当作一般的方法
[NonAction]
Public ActionResult Index()
{}

2.Action 的附加属性
常用的附加属性有
属性名称   说明
HttpGet   用户端使用GET方法向服务器发送请求.SELECT
HttpPost   用户端使用POST方法向服务器发送请求.Insert
HttpDelete  请求服务器删除资料.DELETE
HttpPut   请求服务器更新,新增 资料.INSERT ,UPDATE

客户端使用GET的方法是以QUERYSTRING的方式将数据加在URL后面向服务器请求,此种方法安全性低且数据有长度限制,例如:
http://website/Home/Show?index=1&name=’Jacky’
对应于以下Controller Show

Public class HomeController:Controller
{
  [HttpGet]  //注:预设为GET,所以可以省略不写
Public ActionResult Show(int index,string name)
 {}
}

客户端使用POST的方法是将资料放在数据主体内(request body)进行传输,经常配合表单使用,相比较为安全且没有长度限制.例如:
前端:

<form method = “post” action=”Home/Create”>
<p>Company<input type =”text” name=”Company” id = “txtCompany”></p>
<p>Address<input type=”text” name =”Address” id=”txtAddress”></p>
<p><input type=”submit” value=”Save”></p>
</form>

//注意:的name 是表单的字段,与后台对应.Id 属性由前端js交互使用.
后台Controller:

Public class HomeController:Controller
{
 [HttpPost]
 Public ActionResult Create(string Company,string Address) //对应页面的控件 name
  { }
}
}

再举一个粟子:

Public class HomeController:Controller
{
 [HttpPost]
 Public ActionResult Create(string Company,string Address) //对应页面的控件 name
  { }
}
  public string ShowArray()
        {
            int[] arrScore = { 10, 65, 98, 45, 73 };
            string rtnString = "";
            arrScore.ToList().ForEach(o =>
            {
                rtnString += "," + o.ToString();
            });
            rtnString += "<br />";
            rtnString += "Total:" + arrScore.Sum().ToString();
            return rtnString;
        }
}

http://website/Home/ShowArray

(四) ViewData , ViewBag , TempData 的使用.从服务器Controller传输资料到View.适合少量的数据传递.

1. ViewData : 继承自Dictionary类别,以键/值的方式存取资料
 ViewData的只在当前当前的请求中有效,生命周期和View相同,其值不能在多个请求中共享。
 ViewBag和ViewData存储的值的生命周期只有在从Controller到View中
 在重定向(redirection)后,ViewData中存储的变量值将变为null。
 在取出ViewData中的变量值是,必须进行合适的类型转换(隐式或显式)和空值检查

Eg:
Code:

Public class HomeController:Controller
{
 Public ActionResult Index()
   {
     ViewData[“Company”] = “ETS company”;
   return View();
}
}

Cshtml Page:

<div>
  <h1>@ViewData[“Company”]</h1> /* ETS company  */
</div>

2.ViewBag: 使用dynamic类型,当然速度和损耗上比ViewData差.
使用:

Code:
ViewBag.Company = “ETS company”;

CSHTML PAGE:

@ViewBag.Company

**3.TempData:**与ViewData一样也是属于Dictionay类型.但是TempData是将资料存储在Session中,它的生命周期默认是一个请求(Request), 並將在訪問資料的第一個請求結束時自動刪除。如果從未讀過,它將一直保留到最後讀取或會話超時。通过TempData ,可以将资料跨不同Controller 和Action方法并传递到View.
儲存到 TempData 的資料儲存在會話中,

Eg1:

 public ActionResult Index()
        {
            TempData["tempdata"] = "this is a test";
            var tToDo = dbentity.tToDoes.OrderByDescending(o => o.fDate).ToList();
            return View(tToDo);
           
        }
         public string GetTempData()
            {
               var tempStr = TempData["tempdata"].ToString();//第二次访问时会报null object错误
               return tempStr;
            }

Eg2:
CODE:
public ActionResult DisplayCustomer1()
{
    Customer customer = new Customer
    {
        Id = 1001,
        Code = "100101",
        Amount = 100
    };

    TempData["OneCustomer"] = customer;

    return RedirectToAction("DisplayCustomer2");
}

public ActionResult DisplayCustomer2()
{
    Customer customer = TempData["OneCustomer"] as Customer;

    return View(customer);
}

Page:

在这里插入图片描述

如果要将TempData的资料持久化,可以使用keep或peek的方法
例子:keep

public class TempDataController : Controller
    {
        public ActionResult Index()
        {
            TempData["cnblogs"] = "xpy0928";
            TempData.Keep();
            return View();
        }

        public ActionResult GetTemData()
        {
            var blogName = TempData["cnblogs"].ToString();
            TempData.Keep("cnblogs");
            return View();
        }
    }

例子: Peek,你可以檢索儲存在 TempData 中的資料,而不會將其標記為刪除,因此將來的請求仍然可以使用資料

//first request, save value to TempData
TempData["value"] = "someValueForNextRequest";
    
//second request, PEEK value so it is not deleted at the end of the request
object value = TempData.Peek("value");
    
//third request, read value and mark it for deletion
object value = TempData["value"];

总结:
1)当利用TempData对象存储值而未调用TempData.Keep方法时,此时只要该对象被已读,然后该对象中的所有项将被标记为删除状态。
(2)若调用TempData.Keep(string key)方法,此时不会进行标记删除。
(3)RedirectToRouteResult和RedirectResult总是会调用TempData.Keep()方法,保证该对象中的所有项不会被移除。
4.Session
• Session也是ASP.NET MVC程序传递值的一种方式,在用户的整个会话中Session都不会过期。
• Session在同一用户会话过程中的所有请求中有效,比如,刷新页面。
• Session中的值也需要进行类型转换(隐式或显式)和非空检查。
• Session的生命周期是最长的,但是它默认使用的是Cookies来存储数据,所以使用的时候必须注意数据保密的问题。Session主要用在需要在多个Controllers, Actions and Views共享数据(非敏感数据)时使用。

Eg:

public ActionResult DisplayCustomer1()
{
    Customer customer = new Customer
    {
        Id = 1001,
        Code = "100101",
        Amount = 100
    };

    Session["OneCustomer"] = customer;

    return RedirectToAction("DisplayCustomer2");
}

public ActionResult DisplayCustomer2()
{
    Customer customer = Session["OneCustomer"] as Customer;

    return View(customer);
}

总结,各种传递方式
           ViewData / ViewBag  TempData  Session
Controller to Controller  NO          YES     YES
Controller to View    YES          YES     YES
View to Controller    NO           NO     YES

(五) 模型关联
MVC可以使用模型关联的方式来取得用户端的资料.
1. 简单模型关联
  前端:

<form method = “post” action=”Home/Create”>
<p>Company<input type =”text” name=”Company” id = “txtCompany”></p>
<p>Address<input type=”text” name =”Address” id=”txtAddress”></p>
<p><input type=”submit” value=”Save”></p>
</form>

//注意:的name 是表单的字段,与后台对应.Id 属性由前端js交互使用.
后台Controller:

Public class HomeController:Controller
{
 [HttpPost]
 Public ActionResult Create(string Company,string Address) //对应页面的控件 name
      tCompany tcompany = new tCompany();
           tcompany. Company = Company;
            tcompany. Address = Address;
            db. tCompany.Add(todo);
           db.SaveChanges();
         return RedirectToAction("Index"); 
}
}

2.复杂模型关联
前端:

<form method = “post” action=”Home/Create”>
<p>Company<input type =”text” name=”Company” id = “txtCompany”></p>
<p>Address<input type=”text” name =”Address” id=”txtAddress”></p>
<p><input type=”submit” value=”Save”></p>
</form>

//注意:的name 是表单的字段,与后台对应.Id 属性由前端js交互使用.

后台:

  1. Company.cs模型
Public class Company
{
  Public string Company{get;set;}
  Public string Address{get;set;}
}
2)	Controller:
Public class HomeController:Controller
{
 [HttpPost]
 Public ActionResult Create(Company company) 
  {
         db. tCompany.Add(company);
           db.SaveChanges();
         return RedirectToAction("Index"); 
 }
}

(六) ActionResult 类型

ActionResult(基类) Helper方法 说明

1.ViewResult View Reurn view web page
Eg:

Public class HomeController :Controller
Public ViewResult Index()
{
  Reurn View();//return View Page
  Return View(db.Company.ToList());//return View with list
  Return View(“About”);
Return View(“About”,db.Company.ToList());
}

2.PartialViewResult PartialView 返回部分视图,可放在其它视图的指定位置
3.RedirectResult Redirect 使用url的方式重新导向到其它动作方法

Public RedirectResult Index()
{
  Return Redirect(~/Home/Login”) //redirect to home login action
  Return Redirect(“http://.....)
}

4.RedirectToRouteResult RedirectToAction
5.RedirectToRoute 重新定向到其它动作方法

Public RedirectToRouteResult Index()
{
  Return RedirectToAction(“Login”);
  Return RedirectToAction(“Page”,new {index=1});//Redirect to Home/Page?index=1
  Return RedirectToAction(“Page”,”Default”,new {index=1});//Default is router name
}

6.ContentResult Content 传回用户自定义的内容型别

7.JsonResult Json Return json object

Public JsonResult Index()
{
  Company company = new Company();
 company.Company = “ETL”;
 company.Address = “HK”;
return Json(company,JsonRequestBehavior.AllowGet); //retrun json string {“Company”:”ETL”,”Address”:”HK”}
}

8.JavaScriptResult JavaScript Return javascript script

Public JavaScriptResult Index()
{
  String myConfirm =confirm(‘delete?);
Return JavaScript(myConfirm);
}

9.FileResult File Return binary stream
Front page:

<body>
    <form method="post" action="@Url.Action("PostFILE")" enctype="multipart/form-data">
        <div>
            <p>file1:<input type="file" name="files" id="jfiles" /></p>
            <p>file2:<input type="file" name="files" id="jfiles" /></p> 
            <input type="submit" value="Save" />
        </div>
    </form>
 </body>

后臺Code:

public ActionResult PostFile()
        {
            return View();
        }
        [HttpPost]
        public ActionResult PostFile(HttpPostedFileBase[] files)
        {
            string fname = "";
            foreach (var file in files)
            {
                if (files != null)
                {
                    fname = file.FileName.Substring(file.FileName.LastIndexOf("\\") + 1);
                    file.SaveAs(Server.MapPath("~/TempFiles") + "\\" + fname);
                }
            }
            return RedirectToAction("ShowFile");
        }
        public string ShowFile()
        {
            string rtnStr = "";
            DirectoryInfo dir = new DirectoryInfo(Server.MapPath("~/TempFiles"));
            FileInfo[] fileInfo = dir.GetFiles();
            foreach (var file in fileInfo)
            {
                rtnStr += file.FullName + "<br />";
            }
            return rtnStr;
        }

10.EmptyResult Return null

四. View视图

view负责资料显示,主要由HTML语法构建. .Net提供了HTML Helper 和 Razor可以更方便构建View.

可以从 Controller 的 Action 中快速生成view
在这里插入图片描述

1. 使用 Razor
Razor是专门为asp.net web应用程序而设计的语言,是写在客户端页面但执行在服务器端的. 以@开头
例如:

@DateTime.Now

显示当前时间

1.1 注解
@* 注解的内容 *@

1.2 C#程序段落
@{
 程序代码...
}
Eg:

@{
  String name = “Jacky”;
 @: My name is @name //@: 输出;@变量名
}
@*Razor使用 if 语句*@
@if(ViewBag.IsLogin) {
<span> Login </span> // or @:Login
}
Else 
{<span> Un Login </span>
}
@*要注意:以下这样写是错误的,因为Razor会认为 Login ,UnLogin是后台c#语句*@
@if(ViewBag.IsLogin) {
 Login 
}
Else 
{
Un Login 
}
@*Razor使用 for  or  foreach*@
      @*Eg:*@
   @{
   String[] names = {“Jacky”,”Mandy”,”Weny”};
}
<ul>
  @foreach(var item in names)
{ 
 <li>
   @item
 </li>
}
</ul>

@*Or for*@
<ul>
 @for(int i=p;i< names.Length;i++)
 {
   <li>
   @names[i]
 </li>

}
</ul>

2. 使用 HTML Helper
在前端页面中可以使用 html helper快速生成html标签,它与HTML标签是可以共存的.
在这里插入图片描述
在这里插入图片描述

3. 强类型HTML Helper的使用
与一般的HTML Helper不同 ,强类型主要是为了避免程序中有无效的资料使用存在,它可以与Model模型的属性进行关联.
Eg:
前端View page 代码

@model db.Models.User 
@Html.TextBoxFor(model => model.UserName,new {@class=”form-control”,placeholder=”please input user name”})

注意:
1. 需和model搭配,@model必须有明确的类别
2. 控件与model类别的属性进行关联,Html Helper产生的控件id,name名称与model类别的属性名称一样.
3. 可以指定控件的属性,例如 css
优点:
1. 执行速度快.
2. 容易除错.
3. 有intellisense辅助,代码编写速度更快.

在这里插入图片描述

@model prjMVC20210420.Models.MemberShip

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>MemberShip</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.Account, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.TextBoxFor(model => model.Account, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Account, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.TextBoxFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Pwd, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.PasswordFor(model => model.Pwd, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Pwd, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.TextBoxFor(model => model.Email, new {  @class = "form-control",type="email"  })
                @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.BirthDay, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.TextBoxFor(model => model.BirthDay, new {  @class = "form-control" ,type="date" })
                @Html.ValidationMessageFor(model => model.BirthDay, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

4. @helper辅助方法的使用
Razor可以在View中创建函数使用.

Eg:

@helper AvgScore(int math,int eng)
{
  Int avg = (math + eng)/2;
@:avg
}

<p>Jacky’s avg score:@ AvgScore(80,90)</p>
<p>Linda’s avg score:@AvgScore(75,93)</p>

5. 一对多的资料表查询
我们经常会用到,从Controller返回的data是几个表的联接而成的数据,而不仅仅是某个指定的Model.
第一 种方法:可以使用ViewModel,即将N个Model合并为一个VIEW.
Eg:

  Pulic class tDeptment  //department model
{ 
   Public int DeptId {set ;get;}
   Public string DeptName {set;get;}
}
  Public class tEmployee //employee model
{
  Public int EmpId {set ;get}
  Public string EmpName {set ;get;}
  Public int DeptId {set;get;}
}

新建一个ViewModel ,包含上述两个model

Public class VwDeptEmp
{
  Public List<tDeptment> department {set;get;}
  Public List<tEmployee> employee{get;set;}
}

Controller:

Public ActionResult Index(int deptId = 1)
{
 VwDeptEmp vm = {
 department = db.tDeptment.where(o=>o.DeptId == deptId).ToList(),
 employee = db.tEmployee.where(o=>o.DeptId == deptId).ToList()
};
Return View(vm);
}

Cshtml

@model prjName.Models. VwDeptEmp
@foreach (var item in Model)
{
 <tr>
 <td>
@Html.DisplayFor(modelItem => item.employee.EmpName</td>
<td>@Html.DisplayFor(modelItem => item. department. DeptName </td>
</tr>
}

第二种方法: 如果表之间(Model之间)存在外键关联,例如上述两个model存在deptId 关联,则可以使用 inclue
Eg:
Controller:

Public ActionResult Index(int deptId = 1)
{
 Var emp = db. tEmployee
           .Include(p=>p.tDeptment);
Return View(emp);
}

第三种: 当然也可以使用dynamic 传给VIEW一个动态松散型的结果(当然,这回到了弱类型的开发方式,个人并不推荐)

Eg. (注:未作实际测试)
Controller:

Public ActionResult Index(int deptId = 1)
{ //
 ViewBag.employee = db. tEmployee.Where (o=>o.DeptId==deptId).GroupJoin(db.tDeptMent,
item1=>item1.DeptId,
item2=>item2.DeptId,
(item1,item2)=>new {
 EmpId = item1.EmpId,
 EmpName = item1.EmpName,
 DeptName = item2.DeptName.FirstOrNull()
}).ToList();          
Return View();
}

Cshtml

@foreach (var item in ViewBag.employee as  List<dynamic>)
{
 <tr>
 <td>
@Html.DisplayFor(modelItem => item.EmpName</td>
<td>@Html.DisplayFor(modelItem => item. DeptName </td>
</tr>
}

第四種:使用 dynamic sampleObject = new ExpandoObject(); 將model 作為dynamic 變量的屬性

Controller:
public ActionResult Index()
{
dynamic rtnData = new ExpandoObject();
rtnData.tCRUD = dbEnti.tCRUDs.ToList(); //第1個model
rtnData.tProj = dbEnti.Projects.ToList(); //第2個model
return View(“vProjectIndex”, “_Layout”, rtnData );
}

View:vProjectIndex

@*@foreach (var item in new List<prjMVC.Models.Project>(Model.tProj)) *@
@foreach (prjMVC.Models.Project item in Model.tProj)
{


@Html.DisplayFor(modelItem => item.ProjectNo)


@Html.DisplayFor(modelItem => item.ProjectDesc)


}

6. View index 资料列表的分页显示
GuGet安装控件 PagedList.Mvc
Eg:

View:

@using PagedList.Mvc;
@using PagedList; 
@model IPagedList<prjMVC20210420.Models.tToDo>

@{
    ViewBag.Title = "Index";
}
<link href="~/Content/PagedList.css" rel="stylesheet" />

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table class="table">
    <tr>
        <th>
           Title
        </th>
        <th>
            Image
        </th>
        <th>
           Date
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
           @item.fTitle
        </td>
        <td>
          @item.fImage
        </td>
        <td>
           @item.fDate
        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id=@item.Id }) |
            @Html.ActionLink("Details", "Details", new { id=@item.Id }) |
            @Html.ActionLink("Delete", "Delete", new { id=@item.Id })
        </td>
    </tr>
}

</table>

@Html.PagedListPager(Model, page => Url.Action("Index", new { page }))

Controller code:

using PagedList.Mvc;
using PagedList;
namespace prjMVC20210420.Controllers
{
    public class HomeController : Controller
    {
         DbEntities dbentity = new DbEntities();
        // GET: Home
        public ActionResult Index(int page =1)
        {
            int pagesize = 3;
            int pagecur = page < 1 ? 1 : page;          
            var tToDo = dbentity.tToDoes.OrderByDescending(o => o.fDate).ToList().ToPagedList(pagecur,pagesize);
            return View(tToDo);
           
        }
}
}

7. 使用 Bootstrap 美化网页(http://getbootstrap.com)

Bootstrap base on HTML,Javascript,CSS的一套前端网页框架套件.提供各种常用页面控件,自适应各种设备屏幕长宽度显示等.
以下是_Layout.cshtml
在这里插入图片描述

8. MVC 前端VIEW的数据檢查
對于HTML5 頁面,在頁面Submit前會自動進相應的控件進行數據檢查.
Eg:

@Html.TextBoxFor(model => model.BirthDay, new {  @class = "form-control" ,type="date",required = “required” placeholder=”please input birth day” })
 
Type: type = date ,email,url,number,range,time,required=”required” etc.

9. Ajax簡單介紹

(Asynchronous Javascript and XML)是一種瀏覽器端的技術,可以不刷新整個頁面的方式與服務器進行數據交換并進行頁面(或頁面部分)刷新.

例子1: Get 方式

前端 JS

<script>
    function SaveData() {        
        var data = '{ fTitle: "How to learn MVC", fImage: "1.png", fDate: "2025-05-06" }';
        $.ajax(
            {
                url: "http://localhost:63534/Home/CreateInAjax?data=" + data,
                type: 'GET',              
                success: function (data) {                   
                    alert(data);
                    location.href = "http://localhost:63534/Home/Index";
                }
            }
        );
    }
</script>

后臺 Controller code:

public string CreateInAjax(string data)
{
try
{ //insert a new record.
dynamic obj = JsonConvert.DeserializeObject(data);
tToDo todo = new tToDo();
todo.fTitle = obj.fTitle;
todo.fImage = obj.fImage;
todo.fDate = obj.fDate;
dbentity.tToDoes.Add(todo);
dbentity.SaveChanges();
return “Save.”;
}
catch
{
return “Fail to save.”;
}

}

例子2:POST 方式
前端 JS

function SaveDataPost() {      
        var data = 'data={ fTitle: "How to learn MVC", fImage: "1.png", fDate: "2025-05-06" }';
        $.ajax(
            {
                url: "http://localhost:63534/Home/CreateInAjaxPost",
                data:data,
                type: 'POST',
                dataType:'text',
                success: function (data) {
                    alert(data);
                    location.href = "http://localhost:63534/Home/Index";
                }
            }
        );
    }

后臺 Controller code:

[HttpPost]
public string CreateInAjaxPost(string data)
{
try
{
dynamic obj = JsonConvert.DeserializeObject(data);
tToDo todo = new tToDo();
todo.fTitle = obj.fTitle;
todo.fImage = obj.fImage;
todo.fDate = obj.fDate;
dbentity.tToDoes.Add(todo);
dbentity.SaveChanges();
return “Save.”;
}
catch
{
return “Fail to save.”;
}
}

10. Web API
ASP.NET Web API 可以創建RESTful應用(提供Get/PUT),提供跨平臺的HTTP服務給用戶端瀏覽器及手機移動等設備使用.相對于web service ,WCF,WEB API在提供的數據格式,數據大小,部署方式方面更具有優勢.

Eg:一個WEB API Controller的例子

Public class DefaultController:ApiController
{
  // GET: api/ContextTable/5
        [WebApiNew.Helper.JWTFilter]
        [HttpGet]
        public IEnumerable<dynamic> GetList(string paramStr)
        {
            var paramDyn = System.Web.Helpers.Json.Decode(paramStr);
            using (WorkTempEntities wkTmpEnti = new WorkTempEntities())
            {
                var query = wkTmpEnti.ContextTables.AsEnumerable();//.Where (o=> true);  
                string title = paramDyn["Title"];
                if (!string.IsNullOrEmpty(title))
                {
                    query = query.Where(o => o.Title.Contains(title));
                }
                string addTimeFrom = paramDyn["AddTimeFrom"];
                DateTime dtFrom;
                if (!string.IsNullOrEmpty(addTimeFrom) && DateTime.TryParse(addTimeFrom, out dtFrom))
                {
                    query = query.Where(o => o.AddTime >= dtFrom);
                }               
                return query.ToList();
            }
   }}

<待續>

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值