一、初探ASP.NET MVC
1.ASP.NET MVC简介
MVC是一种软件设计模式,即
Model(模型):实现应用程序数据逻辑的应用程序组件,通常被称为数据模型。模型对象会检索模型状态,并将其存储在数据库中。
View(视图):显示应用程序用户界面(UI)的组件。ASP.NET MVC支持Razor视图引擎,所以视图推荐使用CSHTML页面,而不是ASPX页面
Controller(控制器):处理用户交互、使用模型并选择视图来显示界面的组件。
在ASP.NET MVC应用程序中,视图仅显示界面,控制器则用于处理和响应用户输入和交互
例如:控制器处理查询字符串值,并将这些值传递给模型,而模型使用这些值来查询数据库
执行流程:
浏览器请求——>控制器——>模型——>视图——>显示结果
安装ASP.NET MVC5至少需要.NET Framework4.5
2.创建ASP.NET MVC应用程序
文件——>新建——>项目——>C#、Web——>ASP.NET Web应用程序(.NET Framework)——>选择MVC项目模板
2.1.ASP.NET MVC应用程序包含的默认文件和目录的含义:
/App_Data:数据的物理存储区,即本地化的数据库文件或数据文件
/App_Start:包含多个静态配置类,执行应用程序的初始化任务
/Content:放置应用程序的静态内容,如CSS、可下载的文件及音乐文件等
/Controllers:放置控制器文件。控制器文件是后缀名为.cs或.vb的类文件
/Models:放置数据模型对象的文件,如.cs、.vb、.edmx和.dbml等
/Scripts:放置JavaScript、jQuery文件,文件后缀名通常为.js
/Views:放置视图文件,文件后缀名为.cshtml或.aspx
/Global.asax:全局应用程序类文件
/Web.config:应用程序配置文件
3.控制器基础
右键Controllers目录——>添加——>控制器——>MVC 5 控制器-空
3.1.控制器相关规范:
控制器类名须由Controller结尾
控制器类的基类是Controller类
控制器必须包含至少一个返回值为ActionResult的public方法,这类方法称为操作(Action)方法
4.视图
4.1.添加视图
控制器代码页面——>右键——>添加视图
4.2.模板
一旦选择一个模型类型,就可以选择一个基架模板。这些模板利用Visual Studio模板系统来生成基于选择模型的视图
视图基架类型 | |
基架 | 描述 |
Create | 创建一个视图,其中带有创建模型新实例的表单,并为模型类型的每一个属性生成一个标签和输入框 |
Delete | 创建一个视图,其中带有删除现有模型实例的表单,并为模型的每一个属性显示一个标签以及当前该属性的值 |
Details | 创建一个视图,他包含了模型类型的每一个属性的标签及其相应值 |
Edit | 创建一个视图,其中带有编辑现有模型实例的表单,并未模型类型的每一个属性生成一个标签和输入框 |
Empty | 创建一个空视图,使用@model语法指定模型类型 |
Empty(without model) | 与Empty基架一样创建一个空视图。但是,由于这个基架没有模型,因此选择此基架模型不需要选择模型类型。这是唯一不需要选择模型类型的一个基架类型(常用) |
List | 创建一个带有模型实例表的视图,为模型类型的每一个属性生成一列,确保操作方法向视图传递的是IEnumerable<YourModelType>类型。同时为了执行创建/编辑/删除操作,视图中还包括了指向操作的链接(数据管理常用) |
4.3.创建分部视图
勾选了这个选项表示要创建的视图不是一个完整的视图,而是一个部分视图。通常创建网站的头部和脚部试图页需要勾选此选项
4.4.引用脚本库
这个选项用来指示要创建的视图是否包含指向JavaScript库的引用。默认情况下,_Layout.cshtml文件中引入主JQuery库。创建的基架类型为Empty(without model)的不能勾选此选项
4.5.使用布局页
这个选项是指创建视图的时候需要引用布局创建的部分视图,而不是引用布局创建一个完整的、独立的视图。在_ViewStart.cshtml文件中指定了默认的布局。如果不需要更改就不需要重新指定。这个选项主要是用来重写默认布局文件
4.6.模板页面
在ASP.NET MVC应用程序中,依然沿用了MasterPage(母版页)技术的理念,使用布局页、页面片段和分部视图等视图技术。
4.6.1._ViewStart.cshtml
该文件默认位置:/Views/_ViewStart.cshtml。它的特点是预加载。在Views目录下的任何视图页面被载入前,_ViewStart.cshtml会预先加载,即页面执行前,会寻找是否存在此文件,如果存在,则先载入_ViewStart.cshtml执行。
打开该文件,默认代码仅有一句@{Layout="~/Views/Shared/_Layout.cshtml";},表示Views目录下的所有视图,以/Views/Shared/_Layout.cshtml为布局模板页面
4.6.2._Layout.cshtml
该文件默认位置:/Views/Shared/_Layout.cshtml.它通常称为布局页、母版视图和模板页等,他有两端特别的Razor声明。
4.6.2.1.@RenderBody。它起到"body占位符"的作用,将_Layout.cshtml作为母版页的子视图页面,在没有特别声明的情况下,子视图页面的所有内容填入到_Layout.cshtml的@RenderBody所在位置
4.6.2.2.@RenderSection。它的作用是块占位符,即以指定名称的方式,将子页面中定义的代码块填入到_Layout.cshtml的@RenderSection所在位置
二、数据传递
1.控制器向视图传递值(一)
1.1.ViewData对象
键值对形式
object类型需转换
ViewData只在一次HTTP请求中有效,当这次请求结束后,会自动清空其值
ViewData["Message"]="使用ViewData传递文本数据";
变量名
@ViewData["Message"]
1.2.ViewBag对象
被声明为一个dynamic类型,不需要类型转换
dynamic只存在于编译时刻,而不存在于运行时刻
ViewBag.Name="张三";
变量名
@ViewBag.Name
1.3.TempData对象
可跨Action()方法传递数据
TempData["Message"]="使用TempData传递数据";
变量名
@TempData["Message"]
public ActionResult Index()
{
//控制器的值传递到视图
//ViewData
ViewData["message"] = "张三";
//ViewBag
ViewBag.name = "邓美玉";
//TempData
TempData["accuptation"] = "老师";
return View();
}
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
<h1>使用ViewData传递文本数据</h1>
<h1>@ViewData["message"]</h1>
<h1>使用ViewBag传递文本数据</h1>
<p>@ViewBag.name</p>
<h1>使用TempData跨页面传递文本数据</h1>
<a href="/HY/About"></a>
</div>
</body>
</html>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>About</title>
</head>
<body>
<div>
<h1>@TempData["accuptation"]</h1>
</div>
</body>
</html>
2.控制器向视图传递值(二)
因为ViewDataDictionary类型的内容可以存储任意数据,所有可以把整个Model数据放入ViewData对象或ViewBag对象中传递至View视图页
例:查询user表将数据显示到视图上
using demo2.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace demo2.Controllers
{
public class HYController : Controller
{
// GET: HY
fashionshoppingDBEntities db = new fashionshoppingDBEntities();
public ActionResult UserList()
{
//ViewBag
ViewBag.UserList = db.users.ToList();
//ViewData
ViewData["ulist"] = db.users.ToList();
return View();
}
public ActionResult detail()
{
int id = Convert.ToInt32(Request["id"]);
ViewBag.user= db.users.FirstOrDefault(p => p.userid == id);
return View();
}
}
}
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>UserList</title>
</head>
<body>
<div>
<h1>ViewBag</h1>
<ul>
@foreach (var item in ViewBag.UserList)
{
<li> <a href="/HY/detail?id=@item.userid">@item.username</a> </li>
}
</ul>
<h1>ViewData</h1>
<ul>
@foreach (var item in ViewData["ulist"] as List<demo2.Models.users>)
{
<li><a href="#">@item.username</a></li>
}
</ul>
</div>
</body>
</html>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>detail</title>
</head>
<body>
<div>
<h1>用户详情</h1>
用户名:@ViewBag.user.username <br />
邮箱:@ViewBag.user.email <br />
</div>
</body>
</html>
3.视图传值到控制器
Request对象
例:在文本框中输入用户名,点击提交按钮,将用户名的值传递至控制器方法中,并将该用户名信息保存并输出到视图页上
//get 展示页面
public ActionResult Login()
{
return View();
}
//页面处理请求
[HttpPost]
public ActionResult Save()
{
string name= Request["username"];
string pwd = Request["userpwd"];
ViewBag.message = $"欢迎{name}登录,你的密码是{pwd}";
return View();
}
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Login</title>
</head>
<body>
<div>
<form action="Save" method="post">
用户名:<input type="text" name="username" /><br />
密码:<input type="text" name="userpwd" /><br />
<input type="submit" name="登录" /><br />
</form>
</div>
</body>
</html>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Save</title>
</head>
<body>
<div>
<h2>
@ViewBag.message;
</h2>
</div>
</body>
</html>
4.综合案例
例:实现用户点击了某一用户名链接后即可查看用户详情
using demo2.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace demo2.Controllers
{
public class HYController : Controller
{
// GET: HY
fashionshoppingDBEntities db = new fashionshoppingDBEntities();
public ActionResult UserList()
{
//ViewBag
ViewBag.UserList = db.users.ToList();
//ViewData
ViewData["ulist"] = db.users.ToList();
return View();
}
public ActionResult detail()
{
int id = Convert.ToInt32(Request["id"]);
ViewBag.user= db.users.FirstOrDefault(p => p.userid == id);
return View();
}
}
}
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>UserList</title>
</head>
<body>
<div>
<h1>ViewBag</h1>
<ul>
@foreach (var item in ViewBag.UserList)
{
<li> <a href="/HY/detail?id=@item.userid">@item.username</a> </li>
}
</ul>
</div>
</body>
</html>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>detail</title>
</head>
<body>
<div>
<h1>用户详情</h1>
用户名:@ViewBag.user.username <br />
邮箱:@ViewBag.user.email <br />
</div>
</body>
</html>
三、模型绑定
1.模型绑定基础
模型绑定是将浏览器发送的HTTP请求数据转换为.NET对象的过程
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace demo3.Models
{
public class Student
{
public Student(string username, string userage, string userclass)
{
this.username = username;
this.userage = userage;
this.userclass = userclass;
}
public Student()
{
}
public string username { get; set; }
public string userage { get; set; }
public string userclass { get; set; }
}
}
using demo3.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace demo3.Controllers
{
public class HYController : Controller
{
// GET: HY
public ActionResult Index()
{
//模型绑定
return View();
}
//处理登录逻辑
[HttpPost]
/* public ActionResult Save(string username,string userage,string userclass)
{
//模型绑定
//1.简单基本数据绑定
ViewBag.message = $"学生姓名是{username},学生年龄{userage},学生班级{userclass}";
if (username == "admin")
{
return View();
}
else
{
return View("Index");
}
}*/
public ActionResult Save(Student s)
{
//模型绑定
//2.引用(自定义类型)类型绑定
ViewBag.message = $"学生姓名是{s.username},学生年龄{s.userage},学生班级{s.userclass}";
return View();
}
}
}
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
<form method="post" action="/HY/Save">
姓名:<input type="text" name="username"/>
年龄:<input type="text" name="userage"/>
班级:<input type="text" name="userclass"/>
<input type="submit" value="提交"/>
</form>
</div>
<div>@ViewBag.message</div>
</body>
</html>
注意 :
Request.Form:获取表单提交的值
RouteData.Values:获取路由的值
Request.QueryString:获取URL的值
Request.Files:获取上传文件
2.基本类型的绑定
int?称为可空int类型
using demo3.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace demo3.Controllers
{
public class HYController : Controller
{
// GET: HY
public ActionResult Index()
{
//模型绑定
return View();
}
//处理登录逻辑
[HttpPost]
public ActionResult Index(string username,int? userage,string userclass)
{
//模型绑定
//1.简单基本数据绑定
ViewBag.message = $"学生姓名是{username},学生年龄{userage},学生班级{userclass}";
if (username == "admin")
{
return View();
}
else
{
return View("Index");
}
}
}
}
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
<form method="post" action="/HY/Save">
姓名:<input type="text" name="username"/>
年龄:<input type="text" name="userage"/>
班级:<input type="text" name="userclass"/>
<input type="submit" value="提交"/>
</form>
</div>
<div>@ViewBag.message</div>
</body>
</html>
3.复杂类型的绑定
using demo3.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace demo3.Controllers
{
public class HYController : Controller
{
// GET: HY
//2.复杂方法
public ActionResult Register()
{
//绑定集合
/*string[] names = new string[] { "张三", "", "", "", "" };
ViewBag.names = names;*/
//绑定复杂类型集合
Student[] names = new Student[]
{
new Student("张三","18","2"),new Student(), new Student(), new Student(), new Student(),
};
ViewBag.names = names;
//模型绑定
return View();
}
public ActionResult SaveRegister(List<Student> uname)
{
ViewBag.unames = uname;
return View();
}
}
}
文本框的name属性值必须和对应的Action方法参数名保持一致
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Register</title>
</head>
<body>
<div>
<form method="post" action="/HY/SaveRegister">
@*@foreach (var item in ViewBag.names)
{
<input type="text" name="uname" value="@item"/><br />
}*@
@{ int i = 0;}
@foreach (var item in ViewBag.names)
{
<input type="text" name="uname[@i].username" value="@item.username" />
<input type="text" name="uname[@i].userage" value="@item.userage" />
<input type="text" name="uname[@i].userclass" value="@item.userclass" /><br />
i++;
}
<input type="submit" value="提交" />
</form>
</div>
</body>
</html>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>SaveRegister</title>
</head>
<body>
<div>
@foreach (var item in ViewBag.unames)
{
<p>@item.username</p>
}
</div>
</body>
</html>
4.文件上传
需要在站点根目录建立存放上传文件的目录
<form>标签的enctype属性值必须为multipart/form-data,否则浏览器只会发送文件名而不是文件对象本身
using demo3.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace demo3.Controllers
{
public class HYController : Controller
{
//文件上传
public ActionResult Upload()
{
return View();
}
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
if(file != null)
{
if (file.ContentLength == 0)
{
//文件大小(以字节为单位)为0,返回到视图
return View();
}
else
{
//保存文件
//应用程序需要有服务器UploadFile文件夹的读写权限
file.SaveAs(Server.MapPath("~/UploadFile/" + file.FileName));
}
}
return View();
}
}
}
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Upload</title>
</head>
<body>
<div>
<h1>文件上传</h1>
<form action="/HY/Upload" method="post" enctype="multipart/form-data">
选择上传文件:<input name="file" type="file" id="file"/>
<br />
<br />
<input type="submit" name="submit1" value="上传"/>
</form>
</div>
</body>
</html>
四、表单和HTML辅助方法
1.HTML辅助方法
1.1.表单的使用
<form>标签比较强大。如果没有<form>标签,Internet将变成一个只读存档库
<form action="提交的URL" method="get|post">
表单元素
</form>
1.2.HTML辅助方法简介
HTML辅助方法是用于辅助产生HTML的一组系统方法。使用HTML辅助方法能够帮助产生HTML标签和内容,以提高视图的开发速度,避免不必要的语法错误。HTML辅助方法封装在HtmlHepler类中,同时提供多个重载版本,以适应不同开发需求
重载:同一个类中,方法名一样,参数不一样
重写:子类重写父类方法
框架定义的大多数辅助方法都是扩展方法——static修饰,加this,方法名称有一个向下的箭头
1.3.输出超链接 <a>
@Html.ActionLink("链接文字","ActionName")
@Html.ActionLink("链接文字","ActionName","ControllerName")
@Html.ActionLink("链接文字","ActionName",new{id=123,page=5})
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div>
@*同一个控制器跳转*@
@Html.ActionLink("内容页","About")
@*两个控制器跳转*@
@Html.ActionLink("详情页跳转","Index","Home")
@*同一个控制器,传值*@
@Html.ActionLink("商品详情","About",new {id=3 })
</div>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace demo4.Controllers
{
public class HtmlController : Controller
{
// GET: Html
public ActionResult Index()
{
return View();
}
public ActionResult About(int? id)
{
ViewBag.id =$"你所获得的商品ID是:"+ id;
return View();
}
}
}
2.输出表单
HTML辅助方法 | |
HTML辅助方法 | 说明 |
Html.BeginForm() | 输出<form>标签 |
Html.CheckBox() | 输出<input type="checkbox">标签 |
Html.DropDownList() | 输出<select>标签 |
Html.Password() | 输出<input type="password">标签 |
Html.RadioButton() | 输出<input type="radio">标签 |
Html.TextArea() | 输出<textarea>标签 |
Html.TextBox() | 输出<input type="text">标签 |
Html.Hidden() | 输出<input type="hidden">标签 |
第一个参数name,第二个参数value
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>About</title>
</head>
<body>
<div>
<h1>@ViewBag.id</h1>
</div>
<h1>登录表单</h1>
@using (Html.BeginForm("Index", "Home", FormMethod.Post)) {
<fieldset>
<legend>
表单
</legend>
<p>姓名: @Html.TextBox("username")</p>
<p>密码: @Html.Password("pwd")</p>
<p>
性别:
@Html.RadioButton("gender", 1)男
@Html.RadioButton("gender", 0, true)女
</p>
@{
var list = new List<SelectListItem>();
var list1 = new SelectListItem();
list1.Value = "1";
list1.Text = "看书";
list.Add(list1);
var list2 = new SelectListItem();
list2.Value = "2";
list2.Text = "码代码";
list.Add(list2);
var list3 = new SelectListItem();
list3.Value = "3";
list3.Text = "踢足球";
list.Add(list3);
}
<p>爱好: @Html.DropDownList("love", list)</p>
<p>
岗位:
@Html.CheckBox("job", "后端开发")开发
@Html.CheckBox("job", "软件实施")实施
@Html.CheckBox("job", "少儿编程")少儿编程
</p>
<p>备注:@Html.TextArea("remark")</p>
<input type="submit" value="提交"/>
</fieldset>
}
</body>
</html>
3.其他辅助方法
3.1.使用HTML辅助方法载入分部视图
/View/Shared目录右键——添加——MVC 5 分部页
3.2.在布局页中使用分部页
@Html.Partial("分部页名")
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link href="~/Content/adminstyle.css" rel="stylesheet" />
<link href="~/Content/style.css" rel="stylesheet" />
</head>
<body>
<div id="container">
@Html.Partial("_Top")
<div id="content">
@RenderBody()
</div>
<div id="foot">Copyright(c)2008-2010 FasionShopping时尚有限公司 鄂ICP备05009763号</div>
</div>
</body>
</html>
五、表单验证
1.jQuery验证
jQuery可以向表单添加验证功能,它是目前比较常用的客户端脚本验证技术,而客户端验证最大的优势就是即时性,这是服务器验证所无法取代的。
1.1.表单验证的任务可以归纳为5种类型:
必填验证
范围验证
比较验证
格式验证
特殊验证
using demo5.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace demo5.Controllers
{
public class HYController : Controller
{
// GET: HY
//jQuery验证方式验证
public ActionResult Index()
{
return View();
}
}
}
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
</head>
<body>
<div>
<h1>jQuery验证</h1>
@using (Html.BeginForm("Login", "HY", FormMethod.Post))
{
<p>
姓名:@Html.TextBox("uname", "", new { onblur = "checkUser()" })
<span id="unameMessage" style="color:red"></span>
</p>
<p>
密码:@Html.TextBox("upwd", "", new { onblur = "checkpwd()" })
<span id="upwdMessage" style="color:red"></span>
</p>
<p>
确认密码:@Html.TextBox("repwd", "", new { onblur = "repwd()" })
<span id="repwdMessage" style="color:red"></span>
</p>
<input type="submit" value="提交" />
}
</div>
<script type="text/javascript">
$(function () {
$("form").bind("submit", checkForm)
})
function checkUser() {
if ($("#uname").val() == "") {
$("#unameMessage").html("用户名不能为空");
return false;
} else {
$("#unameMessage").html("");
return true;
}
}
function checkpwd() {
if ($("#upwd").val() == "") {
$("#upwdMessage").html("密码不能为空");
return false;
} else {
$("#upwdMessage").html("");
return true;
}
}
function repwd() {
if ($("#repwd").val() != $("#upwd").val()) {
$("#repwdMessage").html("两次密码不一致");
return false;
} else {
$("#repwdMessage").html("");
return true;
}
}
function checkForm() {
if (checkUser() && repwd()) {
return true;
}
return false;
}
</script>
</body>
</html>
1.2.解释
“if($("#uname").val()=="")”表达id为“uname”的元素(此处即文本框)的值是否为空字符串。如果为空,可以将id为“unameMsg”的<span>标签作为必填文本提示信息显示的容器,并且让id为“uname”的文本框重新获得焦点,否则就清空提示文本信息
1.3.注意
在自定义函数checkForm中,“return false”,表示如果验证出现错误,就终止表单提交。一旦验证未通过,程序将不会把数据提交到控制器方法中去。在表单成功提交至控制器方法之前,不会占用服务器任何资源。
2.jQuery插件验证
Validate插件
需要按顺序依次引入
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.metadata.js"></script>
<script src="~/Scripts/jquery.validate.messages_cn.js"></script>
using demo5.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace demo5.Controllers
{
public class HYController : Controller
{
// GET: HY
//jQuery验证插件方式验证
public ActionResult Login()
{
return View();
}
}
}
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Login</title>
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.metadata.js"></script>
<script src="~/Scripts/jquery.validate.messages_cn.js"></script>
</head>
<body>
<div>
<h1>jQuery验证插件方式验证</h1>
@using (Html.BeginForm("Login", "HY", FormMethod.Post,new { id="validateForm"}))
{
<p>
姓名:@Html.TextBox("uname")
</p>
<p>
密码:@Html.TextBox("upwd")
</p>
<p>
确认密码:@Html.TextBox("repwd")
</p>
<input type="submit" value="提交" />
}
</div>
<script type="text/javascript">
$(function () {
$("#validateForm").validate({
rules: {
uname: { required: true },
upwd: { required: true },
repwd: { required: true,equalTo:"#upwd" }
},
messages: {
uname: { required: "请输入用户名" },
upwd: { required: "请输入密码" },
repwd: { required: "请输入确认密码", equalTo: "两次密码不一致" }
}
});
});
</script>
</body>
</html>
3.模型注解验证
在服务器端对数据进行验证
常见的验证API | ||
数据验证API | 示例 | 说明 |
Compare | [Compare("MyOtherProperty")] | 两个属性值必须相同 |
Range | [Range(10,20)] | 其值必须在指定的数值范围内 |
RegularExpression | [RegularExpression("pattern")] | 其值必须匹配正则表达式 |
Required | [Required] | 其值必须非空或不能只是空格 |
StringLength | [StringLength(10)] | 其值长度不能超过给定的最大长度 |
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace demo5.Models
{
public class User
{
[Required(ErrorMessage ="用户名必填")]
public string uname { get; set; }
[Required(ErrorMessage = "密码必填")]
[StringLength(8,MinimumLength =6,ErrorMessage ="密码长度必须是6-8位")]
public string upwd { get; set; }
[Compare("upwd",ErrorMessage ="和上次密码不一致")]
public string repwd { get; set; }
[Required(ErrorMessage = "年龄必填")]
[Range(18,120,ErrorMessage ="年龄必须是18-120岁")]
public int age { get; set; }
}
}
using demo5.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace demo5.Controllers
{
public class HYController : Controller
{
// GET: HY
//模型注解的方式验证
public ActionResult Login1()
{
return View();
}
[HttpPost]
public ActionResult Login1(User u)
{
return View();
}
}
}
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Login1</title>
<style>
.validation-summary-errors{
color:red;
}
.field-validation-error {
color: red;
}
</style>
</head>
<body>
<div>
<h1>模型注解的方式验证</h1>
@using (Html.BeginForm("Login1", "HY", FormMethod.Post, new { id = "validateForm" }))
{
<p>
姓名:@Html.TextBox("uname")@Html.ValidationMessage("uname")
</p>
<p>
年龄:@Html.TextBox("age")@Html.ValidationMessage("age")
</p>
<p>
密码:@Html.TextBox("upwd")@Html.ValidationMessage("upwd")
</p>
<p>
确认密码:@Html.TextBox("repwd")@Html.ValidationMessage("repwd")
</p>
<input type="submit" value="提交" />
@Html.ValidationSummary()
}
</div>
</body>
</html>
六、强类型
1.强类型声明
所谓强类型,是指变量在定义时已经明确指定其类型
在ASP.NET MVC中,强类型最典型的应用是结合视图使用。默认情况下,视图中的Model属性可以由视图代码直接访问,并且为动态类型,意味着可以直接访问Model属性而不需要知道其准确类型。但是,为了提高开发视图的效率和准确性,可以明确指定Model的具体类型,而强类型数据使用了C#的静态属性,Visual Studio对Razor的智能感知功能。
强类型声明的写法是在视图中用@model关键字指定Model属性的类型。
@model 模型对象(集合)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class HYController : Controller
{
// GET: HY
public ActionResult Index()
{
using (fashionshoppingDBEntities db = new fashionshoppingDBEntities())
{
IEnumerable<Product> products = db.Product.ToList();
return View(products);
}
}
}
}
@model IEnumerable<WebApplication1.Models.Product>
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_LayoutDmy.cshtml";
}
<h2>商品列表</h2>
<div class="plist">
<table cellpadding="0" cellspacing="0" class="style1">
<tr>
<td class="style2">
<div style=" width:120px; margin:20px 0 0 5px;">
<span id="Label1" style="color:#FF3399;">服装分类:</span>
<div>
<div onmouseout="expand1(1)" onmouseover="expand(1)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 衣服</a>
</div>
<div id="1" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">短袖</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(2)" onmouseover="expand(2)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 裤子</a>
</div>
<div id="2" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">牛仔裤</a></li>
<li><a href="#">短裤</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(3)" onmouseover="expand(3)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 裙子</a>
</div>
<div id="3" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">短裙</a></li>
<li><a href="#">迷你裙</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(4)" onmouseover="expand(4)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 帽子</a>
</div>
<div id="4" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">棒球帽</a></li>
<li><a href="#">太阳帽</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(5)" onmouseover="expand(5)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 鞋子</a>
</div>
<div id="5" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">运动鞋</a></li>
<li><a href="#">板鞋</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(6)" onmouseover="expand(6)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 手套</a>
</div>
<div id="6" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">女生手套</a></li>
<li><a href="#">女士围巾</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(7)" onmouseover="expand(7)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 围巾</a>
</div>
<div id="7" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">男士围巾</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(8)" onmouseover="expand(8)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 腰带</a>
</div>
<div id="8" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">男士腰带</a></li>
<li><a href="#">女士腰带</a></li>
</ul>
</div>
</div>
</div>
</div>
</td>
<td>
@foreach (var item in Model)
{
<div class="product">
<div class="pic"><a href="#" target="_blank"><img id="Image3" src="~/show_imageurl/show_@item.imageid" style="height:300px;width:225px;border-width:0px;" /></a></div>
<div style="text-align:center;"></div>
<div style="text-align:center;font-weight:bold"> @item.title</div>
<div style="text-align:center;"><a href="#" target="_blank">㊣太平鸟</a></div>
<div style="text-align:center;color:red">¥ @item.marketprice 元</div>
</div>
}
</td>
</tr>
</table>
<div id="AspNetPager1" style="text-align:center;">
<a disabled="disabled" style="margin-right:5px;">首页</a><a disabled="disabled" style="margin-right:5px;">上一页</a><span style="margin-right:5px;font-weight:Bold;color:red;">1</span><a disabled="disabled" style="margin-right:5px;">下一页</a><a disabled="disabled" style="margin-right:5px;">尾页</a>
</div>
<!--列表页end-->
</div>
2.强类型HTML辅助方法
强类型的HTML辅助方法通过Lambda表达式来引用传递到视图中的模型对象
命名规则:HTML辅助方法名+For
强类型HTML辅助方法 | |
强类型HTML辅助方法 | 说明 |
Html.TextBoxFor() | 输出<input type="text">标签 |
Html.TextAreaFor() | 输出<textarea/>标签 |
Html.CheckBoxFor() | 输出<input type="checkbox">标签 |
Html.DropDownListFor() | 输出<select>标签 |
Html.PasswordFor() | 输出<input type="password">标签 |
Html.RadioButtonFor() | 输出<input type="radio">标签 |
Html.ListBoxFor() | 输出<select multiple>标签 |
Html.LabelFor() | 输出<label/>标签 |
Html.HiddenFor() | 输出<input type="hidden">标签 |
Html.EditorFor() | 根据提供的数据类型生成相应<input>标签(模板型方法) |
Html.DisplayFor() | 根据提供的数据类型生成相应显示内容(模板型方法) |
Html.DisplayTextFor() | 显示数据类型的文字资料 |
Html.ValidationMessageFor() | 显示数据模型输入验证失败时的错误信息 |
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class HYController : Controller
{
// GET: HY
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(Users u)
{
using (fashionshoppingDBEntities db = new fashionshoppingDBEntities())
{
Users user= db.Users.FirstOrDefault(p => p.email == u.email && p.pwd == u.pwd);
if (user!=null)
{
return RedirectToAction("Index");
}
else
{
ModelState.AddModelError("","用户名密码错误");
return View();
}
}
}
}
}
@model WebApplication1.Models.Users
@{
ViewBag.Title = "Login";
Layout = "~/Views/Shared/_LayoutDmy.cshtml";
}
<h2>Login</h2>
<div class="in_zt">
<div class="login_zt">
<div class="border1_t"></div>
<div class="border1_m_zt">
<div class="border1_m_zt_l">
<div class="login_l">
<div style="margin-bottom:30px;"> 会员登录</div>
<div>
@using (Html.BeginForm())
{
<table>
<tr>
<td width="60">Email</td>
<td>
@Html.TextBoxFor(u=>u.email,new { style = "width:124px;" })
</td>
</tr>
<tr>
<td>密码 </td>
<td>
@Html.PasswordFor(u => u.pwd, new { style = "width:124px;" })
</td>
</tr>
<tr>
<td>验证码 </td>
<td>
<input name="vcode" type="text" id="vcode" style="width:62px;" />
<img alt="验证码" src="images/vcode.PNG" title="点击" style=" margin-bottom:-5px; cursor:pointer;" />
</td>
</tr>
<tr>
<td></td>
<td>
<input id="memberUser" type="checkbox" name="memberUser" checked="checked" />
记住用户名
</td>
</tr>
<tr>
<td></td>
<td style="height:60px;">
<input type="image" name="btn" id="btn" src="images/but_login.gif" style="border-width:0px;" />
<br />
<br /> <a href="Register.aspx">立即注册</a>
</td>
</tr>
</table>
}
</div>
</div>
<div class="login_r">
<img src="images/yqtx.gif" />友情提示:<br />
实行会员制,如果您还没有注册,请点击“立即注册”按钮填写相关信息注册成为网站会员,注册之后您可以: <br />
1. 保存您的个人资料<br />
2. 收藏您关注的商品<br />
3. 享受会员服务<br />
4. 订阅本店商品信息<br />
</div>
<div style="color:red;">
@Html.ValidationSummary();
</div>
</div>
</div>
<div class="border1_b"></div>
</div>
</div>
注意:
HTML.LabelFor输出为<label>标签,其文字内容来自模型对象的数据注解。如果输出的<label>标签没有文字内容,需要检查Sysuser类是否使用了[Display]为username和pwd属性设置中文名称
3.强类型视图
Visual Studio为强类型视图提供了支架模板,它结合数据模型对象,自动生成支持增删改查的视图和控制器代码,提高了开发效率。
支架模板功能只能在强类型视图基础上使用。
选择项目中Controllers目录——右键新建——控制器——选择包含视图的MVC5控制器(使用Entity Framework)——选择模型类,数据上下文类
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码已从模板生成。
//
// 手动更改此文件可能导致应用程序出现意外的行为。
// 如果重新生成代码,将覆盖对此文件的手动更改。
// </auto-generated>
//------------------------------------------------------------------------------
namespace WebApplication1.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class Sysuser
{
[Display(Name ="用户编号")]
public int id { get; set; }
[Display(Name = "用户姓名")]
public string username { get; set; }
[Display(Name = "用户密码")]
public string pwd { get; set; }
[Display(Name = "用户角色")]
public Nullable<int> role { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class SysusersController : Controller
{
private fashionshoppingDBEntities db = new fashionshoppingDBEntities();
// GET: Sysusers
public ActionResult Index()
{
return View(db.Sysuser.ToList());
}
// GET: Sysusers/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Sysuser sysuser = db.Sysuser.Find(id);
if (sysuser == null)
{
return HttpNotFound();
}
return View(sysuser);
}
// GET: Sysusers/Create
public ActionResult Create()
{
return View();
}
// POST: Sysusers/Create
// 为了防止“过多发布”攻击,请启用要绑定到的特定属性。有关
// 详细信息,请参阅 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "id,username,pwd,role")] Sysuser sysuser)
{
if (ModelState.IsValid)
{
db.Sysuser.Add(sysuser);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(sysuser);
}
// GET: Sysusers/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Sysuser sysuser = db.Sysuser.Find(id);
if (sysuser == null)
{
return HttpNotFound();
}
return View(sysuser);
}
// POST: Sysusers/Edit/5
// 为了防止“过多发布”攻击,请启用要绑定到的特定属性。有关
// 详细信息,请参阅 https://go.microsoft.com/fwlink/?LinkId=317598。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "id,username,pwd,role")] Sysuser sysuser)
{
if (ModelState.IsValid)
{
db.Entry(sysuser).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(sysuser);
}
// GET: Sysusers/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Sysuser sysuser = db.Sysuser.Find(id);
if (sysuser == null)
{
return HttpNotFound();
}
return View(sysuser);
}
// POST: Sysusers/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Sysuser sysuser = db.Sysuser.Find(id);
db.Sysuser.Remove(sysuser);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
@model IEnumerable<WebApplication1.Models.Sysuser>
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_adminLayout.cshtml";
}
<h2>管理员列表页</h2>
<p>
@Html.ActionLink("新增", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.username)
</th>
<th>
@Html.DisplayNameFor(model => model.pwd)
</th>
<th>
@Html.DisplayNameFor(model => model.role)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.username)
</td>
<td>
@Html.DisplayFor(modelItem => item.pwd)
</td>
<td>
@*@Html.DisplayFor(modelItem => item.role)*@
@((item.role==1)?"超级管理员":"普通管理员")
</td>
<td>
@Html.ActionLink("编辑", "Edit", new { id=item.id }) |
@Html.ActionLink("详情", "Details", new { id=item.id }) |
@Html.ActionLink("删除", "Delete", new { id=item.id })
</td>
</tr>
}
</table>
@model WebApplication1.Models.Sysuser
@{
ViewBag.Title = "Details";
Layout = "~/Views/Shared/_adminLayout.cshtml";
}
<h2>管理员详情</h2>
<div>
<h4>Sysuser</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.username)
</dt>
<dd>
@Html.DisplayFor(model => model.username)
</dd>
<dt>
@Html.DisplayNameFor(model => model.pwd)
</dt>
<dd>
@Html.DisplayFor(model => model.pwd)
</dd>
<dt>
@Html.DisplayNameFor(model => model.role)
</dt>
<dd>
@*@Html.DisplayFor(model => model.role)*@
@((Model.role==1)?"超级管理员":"普通管理员")
</dd>
</dl>
</div>
<p>
@Html.ActionLink("编辑", "Edit", new { id = Model.id }) |
@Html.ActionLink("返回列表", "Index")
</p>
@model WebApplication1.Models.Sysuser
@{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_adminLayout.cshtml";
}
<h2>添加管理员</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Sysuser</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.username, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.username, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.username, "", 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.EditorFor(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.role, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownListFor(model => model.role, new SelectListItem[] {
new SelectListItem{ Text="超级管理员",Value="1"},
new SelectListItem{ Text="普通管理员",Value="0"},
},new { @class="form-control"})
@Html.ValidationMessageFor(model => model.role, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="新增" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("返回列表", "Index")
</div>
@model WebApplication1.Models.Sysuser
@{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_adminLayout.cshtml";
}
<h2>编辑管理员</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Sysuser</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.id)
<div class="form-group">
@Html.LabelFor(model => model.username, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.username, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.username, "", 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.EditorFor(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.role, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.role, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.role, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="保存" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("返回列表", "Index")
</div>
@model WebApplication1.Models.Sysuser
@{
ViewBag.Title = "Delete";
Layout = "~/Views/Shared/_adminLayout.cshtml";
}
<h2>删除管理员</h2>
<h3>Are you sure you want to delete this?</h3>
<div>
<h4>Sysuser</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.username)
</dt>
<dd>
@Html.DisplayFor(model => model.username)
</dd>
<dt>
@Html.DisplayNameFor(model => model.pwd)
</dt>
<dd>
@Html.DisplayFor(model => model.pwd)
</dd>
<dt>
@Html.DisplayNameFor(model => model.role)
</dt>
<dd>
@*@Html.DisplayFor(model => model.role)*@
@((Model.role==1)?"超级管理员":"普通管理员")
</dd>
</dl>
@using (Html.BeginForm()) {
@Html.AntiForgeryToken()
<div class="form-actions no-color">
<input type="submit" value="删除" class="btn btn-danger" /> |
@Html.ActionLink("返回列表", "Index")
</div>
}
</div>
七、AJAX
1.通过jQuery实现AJAX传值
AJAX是Asynchronous JavaScript(异步JavaScript)与XML的缩写。这是在后台请求服务器数据,而不必重载Web页面的一种技术
其中最核心的依赖是浏览器提供的对象(XMLHttpRequest,XHR)
例:实现用户注册用户名的验证功能
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class DmyController : Controller
{
// GET: Dmy
public ActionResult Register()
{
return View();
}
//验证用户名是否可以用,false:验证未通过,true:验证通过
public ActionResult ValidateUser(string username)
{
//去数据库里面查询用户名称等于用户输入的,判断是否存在
using(fashionshoppingDBEntities db=new fashionshoppingDBEntities())
{
if (db.Users.Where(p=>p.email==username).Count()>0)
{
//存在
return Content("false");//Content内容
}
else
{
return Content("true");
}
}
}
}
}
@{
ViewBag.Title = "Register";
Layout = "~/Views/Shared/_LayoutDmy.cshtml";
}
<h2>用户注册</h2>
<div>
用户名:@Html.TextBox("username");
<input type="button" value="注册" onclick="checkUser()" />
<span id="msg"></span>
</div>
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
function checkUser() {
$.ajax({
url:"/Dmy/ValidateUser",//方法名
type:"GET",//请求方式
data: { "username": $("#username").val()},//入参
success: function (data) {
if (data == "true") {
$("#msg").html("<font color='green'>用户名可以注册</font>");
} else {
$("#msg").html("<font color='red'>用户名已存在</font>");
}
},
error: function (xhr, error, ex) {
$("#msg").html("<font color='red'>出错了请重试</font>");
}
});
}
</script>
解释:
url:发送请求的地址
type:HTTP请求方式
data:发送到服务器的数据,jQuery将其转换为请求字符串格式,如将{foo:["bar1","bar2"]}转换为"&foo=bar1&foo=bar2"
contentType:内容编码类型,默认是application/x-www-form-urlencoded
success:请求成功后的回调函数
error:AJAX请求失败时调用的函数
注意:
若从Action()方法返回的消息仅仅只是一个字符串文本,可使用return Content()方法返回改消息文本
2.AJAX辅助方法——Ajax.ActionLink
Ajax.ActionLink
ASP.NET MVC框架中的HTML辅助方法,可以创建表单和指向控制器操作方法的超链接。在ASP.NET MVC框架中,还包含一组AJAX辅助方法,他们同样可以用于创建表单和指向控制器操作方法的超链接。不同的是,它们与服务器采用的是AJAX(异步交互)方式,当使用AJAX辅助方法时,无须编写任何脚本代码即可实现程序的异步性。在ASP.NET MVC中,使用AJAX辅助方法必须先引用jquery.unobtrusive-ajax.min.js,此文件默认包含在ASP.NET MVC应用程序模板中,在创建ASP.NET MVC应用程序后,可以通过编码引用它。在Razor视图中,AJAX辅助方法通过@AJAX调用,如@Ajax.ActionLink、@Ajax.BeginForm。
Ajax.ActionLink()方法可以创建一个具有异步行为的超链接。ActionLink()方法的第一个参数是超链接的文本,第二个参数是操作方法的名称。ActionLink()方法可以通过设置AjaxOptions对象的属性值来调整AJAX请求的行为
AjaxOptions对象的一套属性能够配置对服务器的异步请求,以及处理返回的数据。
AjaxOptions属性 | |
属性 | 作用 |
Confirm | 获取或设置提交请求之前,显示在确认窗口中的消息 |
HttpMethod | 获得或设置HTTP请求方法(GET或POST) |
InsertionMode | 获取或设置指定如何将响应结果插入到目标DOM元素的模式 |
LoadingElementId | 获取或设置加载时要显示的HTML元素的id属性值 |
OnBegin | 获取或设置更新页面之前调用的JavaScript函数的名称 |
OnComplete | 获取或设置数据响应之后、更新页面之前,调用的JavaScript函数 |
OnFailure | 获取或设置页面更新失败时调用的JavaScript函数 |
OnSuccess | 获取或设置页面更新成功时调用的JavaScript函数 |
UpdateTargetId | 获取或设置要使用服务器响应来更新的DOM元素的id |
Url | 获取或设置要向其发送请求的URL |
@{
ViewBag.Title = "Contact";
}
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<div id="div1">
@Ajax.ActionLink("显示小组成员", "GO", new AjaxOptions
{
UpdateTargetId = "div1",
InsertionMode = InsertionMode.Replace,
HttpMethod = "Get"
});
</div>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WebApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Contact()
{
return View();
}
public ActionResult GO()
{
ViewBag.message= new string[] { "张三", "历史", "王五", "赵柳" };
return PartialView("_PartialPage1");
}
}
}
3.AJAX辅助方法——Ajax.BeginForm
Ajax.BeginForm
例:创建AJAX表单实现数据搜索
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class DmyController : Controller
{
// GET: Dmy
public ActionResult Index()
{
using (fashionshoppingDBEntities db = new fashionshoppingDBEntities())
{
IEnumerable<Product> products= db.Product.ToList();
return View(products);
}
}
public ActionResult Search(string pname)
{
using (fashionshoppingDBEntities db = new fashionshoppingDBEntities())
{
IEnumerable<Product> products = db.Product.Where(p => p.title.Contains(pname)).ToList();
return View("_PartialPage1", products);
}
}
}
}
@model IEnumerable<WebApplication1.Models.Product>
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_LayoutDmy.cshtml";
}
<div class="plist">
<table cellpadding="0" cellspacing="0" class="style1">
<tr>
<td class="style2">
<div style=" width:120px; margin:20px 0 0 5px;">
<span id="Label1" style="color:#FF3399;">服装分类:</span>
<div>
<div onmouseout="expand1(1)" onmouseover="expand(1)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 衣服</a>
</div>
<div id="1" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">短袖</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(2)" onmouseover="expand(2)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 裤子</a>
</div>
<div id="2" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">牛仔裤</a></li>
<li><a href="#">短裤</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(3)" onmouseover="expand(3)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 裙子</a>
</div>
<div id="3" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">短裙</a></li>
<li><a href="#">迷你裙</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(4)" onmouseover="expand(4)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 帽子</a>
</div>
<div id="4" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">棒球帽</a></li>
<li><a href="#">太阳帽</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(5)" onmouseover="expand(5)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 鞋子</a>
</div>
<div id="5" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">运动鞋</a></li>
<li><a href="#">板鞋</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(6)" onmouseover="expand(6)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 手套</a>
</div>
<div id="6" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">女生手套</a></li>
<li><a href="#">女士围巾</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(7)" onmouseover="expand(7)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 围巾</a>
</div>
<div id="7" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">男士围巾</a></li>
</ul>
</div>
</div>
<div onmouseout="expand1(8)" onmouseover="expand(8)">
<div style="width:90px" class="cctelist" onclick="">
<a href="#"> 腰带</a>
</div>
<div id="8" style="margin:0 0 0 10px; width:85px; display:none; ">
<ul class="cc">
<li><a href="#">男士腰带</a></li>
<li><a href="#">女士腰带</a></li>
</ul>
</div>
</div>
</div>
</div>
</td>
<td>
<div style="margin-left:20px;margin-top:20px">
@using (Ajax.BeginForm("Search","Dmy",new AjaxOptions {
UpdateTargetId= "serrchresult",//替换元素id
InsertionMode=InsertionMode.Replace,//替换原内容
HttpMethod="Get",//提交方式
OnFailure="searchFail"//处理失败执行函数
}))
{
<input type="text" name="pname" />
<input type="submit" value="搜索"/>
}
</div>
<div id="serrchresult">
@foreach (var item in Model)
{
<div class="product">
<div class="pic"><a href="#" target="_blank"><img id="Image4" src="~/show_imageurl/show_@item.imageid" style="height:300px;width:225px;border-width:0px;" /></a></div>
<div style="text-align:center;"></div>
<div style="text-align:center;font-weight:bold"> @item.title </div>
<div style="text-align:center;"><a href="#" target="_blank">㊣特价短袖</a></div>
<div style="text-align:center;color:red">¥@item.marketprice 元</div>
</div>
}
</div>
</td>
</tr>
</table>
<div id="AspNetPager1" style="text-align:center;">
<a disabled="disabled" style="margin-right:5px;">首页</a><a disabled="disabled" style="margin-right:5px;">上一页</a><span style="margin-right:5px;font-weight:Bold;color:red;">1</span><a disabled="disabled" style="margin-right:5px;">下一页</a><a disabled="disabled" style="margin-right:5px;">尾页</a>
</div>
<!--列表页end-->
</div>
<script type="text/javascript">
function searchFail() {
$("#serrchresult").html("查询报错!");
}
</script>
八、ASP.NET Web API
1.Web API简介
1.1.Web API的发展历程
移动端和服务端的交互,主流的方式还是通过HTTP协议的形式来进行,请求以GET/POST方式为主,响应以JSON(数据更小巧且描述能力强)方式为主
Web API是一个比较宽泛的概念,她是微软重新审视了所有通信技术的解决方案,集成ASP.NET MVC和WCF里的优秀的技术,重新打造出一个轻量化、高效率的并且可以对接各种客户端(浏览器、智能手机终端、桌面客户端等)的HTTP Service的框架
1.2.什么情况下用Web API——为了更好适应客户端
需要Web Service但是不需要SOAP
需要在已有的WCF服务基础上建立non-soap-based http服务
只想发布一些简单的HTTP服务,不想使用相对复杂的WCF配置
发布的服务可能会被宽带受限的设备访问
希望使用开源框架,关键时候可以自己调试或者自定义框架
1.3Web API的主要功能
支持基于Http verb(GET、POST、PUT、DELETE)的CRUD(create,retrieve,update,delete)操作。即通过不同的HTTP动作表达不同的含义,这样就不需要暴露多个API来支持这些基本操作
请求的回复格式支持JSON、XML,并且可以扩展添加其他格式
原生支持OData
支持Self-host或者IIS host
支持大多数MVC功能,如Routing、Controller、Action Result、Filter、Model Builder、IOC Container和Dependency Injection
1.4.HTTP动词
在Web开发中,HTTP是必不可少的环节
HTTP是一种基于应用层的超文本传输协议。
定义了8个主要的HTTP动词:OPTIONS、GET、HEAD、POST、PUT、DELETE、PATCH、TRACE
HTTP动词是用户端向服务器说明现在想要对资源进行何种动作,服务器端有权审查用户端的请求并进行响应
1.4.1.GET
说明:使用GET动词获取URL资源的具象
请求:按HTTP/1.1规定,只有标头,没有文本
响应:所请求URL资源的具象,通常带有一个文本及Content-Type、Content-Length等类,响应标头要与响应的具象一致
常用场景:一般用于获取查询资源,对应数据库中的Select操作,为HTTP请求常用方法
安全性:安全,因为其只查询而不修改数据
1.4.2.POST
说明:使用POST动词让资源在服务器中执行一系列动作
请求:一个资源的具象
响应:一个资源的具象,或是一个重定向指令
常用场景:一般用于向系统中更新数据,对应数据库中的Insert(多)Update操作,为HTTP请求常用方法
安全性:与GET相比较,POST较安全
1.4.3.PUT
说明:PUT动词用来完整更新或替换一个现有的资源,也可以用用户端指定的URL来建立一个新资源,在Web API2里用于更新一个现存的资源
请求:一个资源的具象
响应:更新的状态
常用场景:一般用于向系统中插入或更新数据,(当然,其功能POST也能实现,与POST有很多相似之处),对应数据库中的Insert、Update(多)操作,为HTTP请求常用方法
安全性:不安全,不带验证机制,故一般不使用该方法
1.4.4.DELETE
说明:使用DELETE动词删除资源
请求:只有标头,没有文本
响应:成功或失败,文本中可以包含操作的状态
常用场景:一般用于向系统中删除数据,对应数据库中的Delete操作
安全性:不安全,不带验证机制
1.4.5.HEAD
HEAD动词用法与GET动词一样,只不过HEAD动词只返回Http-Response头部信息。由于HEAD动词只返回头部信息(相对于GET动词,轻量级),故一般被用于确认URL的有效性、资源更新的日期时间等
资源与HTTP动词 | ||
资源操作 | HTTP动词 | 说明 |
Create | POST | 新增资源 |
Read | GET | 读取资源 |
Update | PUT(PATCH) | 更新资源 |
Delete | DELETE | 删除资源 |
注意:这里的CRUD不单指对数据库的行为,而是指一种操作行为。例如文件也可以有CRUD行为
2.创建Web API MVC应用程序
文件——新建——项目——选择Visual C#|Web模板列表——选择ASP.NET Web应用程序(.NET Framework)——选择模板Web API
解释:
访问Web API控制器时,默认需要添加上api目录,用以和普通控制器区分。若需自定义规则,可在路由配置中更改。
注意:
此处访问端口号根据运行项目时自动分配的端口号而定。
ValuesController派生自System.Web.Http.ApiController类,是一个Web API控制器类
经验:
Web API控制器与普通的控制器相比,有一下3个不同点:
继承System.Web.Http.ApiController类,而非继承System.Web.Mvc.ApiController类
控制器中的方法返回原始对象,而并非视图和其他操作辅助对象
默认根据HTTP动词调度操作,而并非根据名称调度操作
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebAPI.Models;
namespace WebAPI.Controllers
{
public class HYController : ApiController
{
//需求:sysuser这张表做增删改查
// GET: api/HY
public IEnumerable<Sysuser> Get()
{
using (fashionshoppingDBEntities db = new fashionshoppingDBEntities())
{
return db.Sysuser.ToList();
}
}
// GET: api/HY/5
/// <summary>
/// 获取某个具体的资源
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public Sysuser Get(int id)
{
using (fashionshoppingDBEntities db = new fashionshoppingDBEntities())
{
return db.Sysuser.FirstOrDefault(p => p.id == id);
}
}
// POST: api/HY
/// <summary>
/// 更新资源,新增
/// </summary>
/// <param name="value"></param>
public Sysuser Post([FromBody] Sysuser value)
{
using (fashionshoppingDBEntities db=new fashionshoppingDBEntities())
{
db.Sysuser.Add(value);
db.SaveChanges();
return value;
}
}
// PUT: api/HY/5
/// <summary>
/// 更新
/// </summary>
/// <param name="id"></param>
/// <param name="value"></param>FromUrl
public Sysuser Put(int id, [FromBody] Sysuser value)
{
using (fashionshoppingDBEntities db = new fashionshoppingDBEntities())
{
var user = db.Sysuser.FirstOrDefault(p => p.id == id);
if (user != null)
{
user.pwd = value.pwd;
user.username = value.username;
user.role = value.role;
}
db.SaveChanges();
return user;
}
}
// DELETE: api/HY/5
/// <summary>
/// 删除
/// </summary>
/// <param name="id"></param>
public void Delete(int id)
{
using (fashionshoppingDBEntities db=new fashionshoppingDBEntities())
{
var user= db.Sysuser.FirstOrDefault(p=>p.id==id);
if (user !=null)
{
db.Sysuser.Remove(user);
db.SaveChanges();
}
}
}
}
}
3.AJAX调用Web API
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace WebAPI.Controllers
{
public class SysUserController : Controller
{
// GET: SysUser
public ActionResult Index()
{
return View();
}
}
}
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>系统管理员维护</title>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<h1>系统管理员维护</h1>
<div>
<table id="sysUserTable" class="table">
<tr>
<td>
编号
</td>
<td>
账户
</td>
<td>
密码
</td>
<td>
角色(1管理员0普通)
</td>
<td>
操作
</td>
</tr>
</table>
<hr />
<fieldset>
<legend>添加管理员</legend>
账户:<input type="text" id="txtUsername" />
<br />
密码:<input type="text" id="txtPwd" />
<br />
角色:<input type="text" id="txtrole" />
<br />
<input type="button" id="btnInsert" value="添加" />
</fieldset>
</div>
<script src="~/Scripts/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$(function () {
$.getJSON("/api/HY", loadSysUser);
$("#btnInsert").click(OnInsert);
})
//获取所有通过ajax方法
@*function All() {
$.ajax({
type: 'GET',
url: '/api/HY',
//data: data,
contentType: "application/json;charset=utf-8",//返回值类型
dataType: 'json',//入参类型
success: function () {
loadSysUser();
}
});
}*@
//显示所有信息JSON
function loadSysUser(data) {
console.log(data);
$("#sysUserTable").find("tr:gt(0)").remove();//删除表格元素
$.each(data, function (key, val) {
//显示
//var tabbleItem = '<tr><td>' + val.id + '</td ><td>' + val.username + '</td><td>' + val.pwd + '</td><td>' + val.role + '</td><td><input type="button" name="btnUpdate" value="修改" /><input type="button" name="btnDelete" value="删除" class="btn-danger" /></td></tr > ';
//修改需要input可编辑性
var tabbleItem = '<tr><td>' + val.id + '</td ><td><input type="text" value="' + val.username + '"/></td><td><input type="text" value="' + val.pwd + '"/></td><td><input type="text" value="' + val.role + '"/></td><td><input type="button" name="btnUpdate" value="修改" /><input type="button" name="btnDelete" value="删除" class="btn-danger" /></td></tr > ';
$("#sysUserTable").append(tabbleItem);
});
//绑定删除事件
$("input[name='btnDelete']").click(OnDelete);
$("input[name='btnUpdate']").click(OnUpdate);
}
//修改
function OnUpdate() {
//获取id
var id = $(this).parent().parent().children().get(0).innerHTML;
console.log(id);
//获取每个输入框的值
var cell;
cell = $(this).parent().parent().children().get(1);
var username = $(cell).find('input').val();
cell = $(this).parent().parent().children().get(2);
var pwd = $(cell).find('input').val();
cell = $(this).parent().parent().children().get(3);
var role = $(cell).find('input').val();
//拼接json
var data = '{"username":"' + username + '","pwd":"' + pwd + '","role":"' + role + '"}';
$.ajax({
type: 'PUT',
url: '/api/HY/' + id,
data: data,
contentType: "application/json;charset=utf-8",//返回值类型
dataType: 'json',//入参类型
success: function () {
//刷新页面
$.getJSON("/api/HY", loadSysUser);
alert("修改成功");
}
});
}
//删除
function OnDelete() {
//获取删除的ID
var id = $(this).parent().parent().children().get(0).innerHTML;
console.log(id);
//调用ajax
$.ajax({
type: 'DELETE',
url: '/api/HY/' + id,
//data: data,//入参,此处没有入参,因为id被拼接到url
contentType: "application/json;charset=utf-8",//返回值类型
dataType: 'json',//入参类型
success: function () {
//刷新页面
$.getJSON("/api/HY", loadSysUser);
alert("删除成功");
}
});
}
//新增
function OnInsert(evt) {
console.log("开始新增");
var username = $("#txtUsername").val();
var pwd = $("#txtPwd").val();
var role = $("#txtrole").val();
var data = '{"username":"' + username + '","pwd":"' + pwd + '","role":"' + role + '"}';
$.ajax({
type: 'POST',
url: '/api/HY',
data: data,
contentType: "application/json;charset=utf-8",//返回值类型
dataType: 'json',//入参类型
success: function () {
$("#txtUsername").val('');
$("#txtPwd").val('');
$("#txtrole").val('');
//刷新页面
$.getJSON("/api/HY", loadSysUser);
alert("添加成功");
}
});
}
</script>
<script src="~/Scripts/bootstrap.js"></script>
</body>
</html>
注意:AJAX默认的contentType是application/x-www-form-urlencoded,此处需要改成application/json;charset=utf-8,否则无法获取数据
九、控制器和路由
1.ActionResult对象
1.1.ActionResult对象
在ASP.NET MVC中,一个控制器可以包含多个操作方法,每一个操作方法都返回一个ActionResult实例对象,然后呈现视图页面。ActionResult是一个抽象的基类。
ActionResult派生类型 | |
ActionResult派生类型 | 作用 |
ViewResult | 用于返回标准的视图页面 |
EmptyResult | 不返回任何数据 |
ContentResult | 以字符串的形式指定响应的内容 |
FileResult | 返回任意文档内容 |
JavaScriptResult | 响应一段JavaScript脚本内容 |
1.2.ContentResult对象
ContentResult使ASP.NET MVC 按照指定的内容响应请求。可以使用ContentResult的Content属性以字符串的形式指定响应的内容,其中两个属性ContentEncoding和ContentType用于指定字符编码方式和媒体类型(MIME类型)
注意:视图中的核心部分是用于引用css文件的<link>标签,可以看到它的href属性指向的地址对应着css操作方法,最终用于控制页面样式的css通过调用该操作符方法而获得
1.3.FileResult对象
FileResult可以输出文件内容,它包含3个派生类型FileContentResult、FilePathResult和FileStreamResult。FileContentResult是针对文件内容创建的FileResult对象,FilePathResult是根据物理文件路径创建的FileResult对象,FileStreamResult是允许通过一个用于读取文件内容的流来创建的FileResult对象。
2.过滤器
通常情况下,控制器的操作方法在执行前后需要运行一些逻辑运算,并处理一些运行过程中所产生的异常状况。为了满足该要求,ASP.NET MVC提供过滤器(Filter)来处理这些需求,支持的过滤器类型有4种,分别是Authorization(授权)、Exception(异常)、Action(行为)、Result(结果)
过滤器 | ||
过滤器 | 接口 | 描述 |
Authorization | IAuthorizationFilter | 用于限制执行控制器或控制器的某个操作方法 |
Exception | IExceptionFilter | 用于指定一个操作,用于处理控制器中抛出的异常 |
Action | IActionFilter | 用于执行操作之前或之后的处理 |
Result | IResultFilter | 用于返回结果之前或之后的处理 |
2.1.授权过滤器
最先运行的过滤器,可以用于对操作方法在正式运行前进行一些额外的判断。例如授权检查,验证是否为SSL完全链接以及验证输入信息是否包含攻击字符串等。
例:使用授权过滤器结合登录验证功能实现页面的授权访问,以此加强登录功能
2.1.1.创建控制器和方法
控制器和操作方法 | ||
控制器 | 操作方法 | 作用 |
HomeController | public ActionResult Index() | 显示首页 |
AccountController | [Authorize] public ActionResult Index() | 显示用户设置页面(授权访问) |
public ActionResult LogOn() | 显示登录页 | |
[HttpPost] public ActionResult LogOn(User user) | 登录信息提交 |
2.1.2.打开应用程序根目录的Web.config,在<system.web>节点下修改<authentication >节点内容,以启用Forms验证和设置默认的登录页面
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.7.2" />
<authentication mode="Forms">
<forms loginUrl="~/Admin/Login" timeout="2880">
</forms>
</authentication>
</system.web>
表示当前应用程序使用Forms身份验证,其登录页面为 /Admin/Login.cshtml,Cookie的过期时间是2880分钟
2.1.3.为数据模型对象添加模型验证的数据注解
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码已从模板生成。
//
// 手动更改此文件可能导致应用程序出现意外的行为。
// 如果重新生成代码,将覆盖对此文件的手动更改。
// </auto-generated>
//------------------------------------------------------------------------------
namespace WebApplication1.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class Sysuser
{
[Display(Name ="用户账号")]
public int id { get; set; }
[Display(Name = "用户姓名")]
[Required(ErrorMessage = "用户名必须填写")]
public string username { get; set; }
[Display(Name = "用户密码")]
[Required(ErrorMessage ="密码必须填写")]
public string pwd { get; set; }
[Display(Name = "用户角色")]
public Nullable<int> role { get; set; }
}
}
2.1.3.控制器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class AdminController : Controller
{
// GET: Admin
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(Sysuser sysuser)
{
using(fashionshoppingDBEntities db=new fashionshoppingDBEntities())
{
var user = db.Sysuser.Where(p=>p.username==sysuser.username&&p.pwd==sysuser.pwd).FirstOrDefault();
if (user != null)
{
FormsAuthentication.SetAuthCookie(sysuser.username, false);
return RedirectToAction("Index", "Sysusers");
}
}
return View();
}
}
}
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using WebApplication1.Models;
namespace WebApplication1.Controllers
{
public class SysusersController : Controller
{
private fashionshoppingDBEntities db = new fashionshoppingDBEntities();
// GET: Sysusers
[Authorize]
public ActionResult Index()
{
return View(db.Sysuser.ToList());
}
}
}
2.1.4.页面
@{
Layout = null;
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>
管理员登陆
</title>
<link href="/Content/adminstyle.css" type="text/css" rel="stylesheet" />
</head>
<body style="margin-top: 0">
@using (Html.BeginForm("Login", "Admin", FormMethod.Post))
{
<form id="form1" name="form1" method="post" action="" style="width: 100%; height: 100%; text-align: center;">
<div id="main">
<div id="logoStyle" dir="ltr" style="">
<div>
用户名:
@Html.TextBox("username", "100", new { @class = "ipt" })
</div>
密 码: @Html.Password("pwd", "100", new { @class = "ipt" })
<br />
类 型:@Html.DropDownList("role", new SelectListItem[] { new SelectListItem { Text = "普通管理员", Value = "0" }, new SelectListItem { Text = "超级管理员", Value = "1" } }, new { @class = "sel" })
<br /><br />
<input type="submit" name="Button1" value="登录" id="Button1" class="btn" />
<input type="submit" name="Button2" value="返回" id="Button2" class="btn" />
</div>
</div>
</form>
}
</body>
</html>
@model IEnumerable<WebApplication1.Models.Sysuser>
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_adminLayout.cshtml";
}
<h2>用户管理页面</h2>
<p>
@Html.ActionLink("新增", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.username)
</th>
<th>
@Html.DisplayNameFor(model => model.pwd)
</th>
<th>
@Html.DisplayNameFor(model => model.role)
</th>
<th></th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.username)
</td>
<td>
@Html.DisplayFor(modelItem => item.pwd)
</td>
<td>
@((item.role==1)?"超级管理员":"普通管理员")
</td>
<td>
@Html.ActionLink("编辑", "Edit", new { id=item.id }) |
@Html.ActionLink("详情", "Details", new { id=item.id }) |
@Html.ActionLink("删除", "Delete", new { id=item.id })
</td>
</tr>
}
</table>
十、测试和部署
1.使用Visual Studio测试
为了创建并执行自动化测试代码,需要创建一个测试项目来辅助完成这项工作。在Visual Studio中测试项目是一个类库项目
1.1.创建单元测试
方法一:解决方案——右键添加——新建项目——单元测试项目(.NET Framework) Visual C#
方法二:在新建MVC应用程序时——在对话框中勾选“添加单元测试”
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
namespace UnitTestProject1
{
//单元测试类
[TestClass]
public class UnitTest1
{
//测试方法
[TestMethod]
public void TestMethod1()
{
int sum = 1 + 2;
//检查sum结果是否为3
Assert.AreEqual(3, sum);
}
}
}
运行单元测试:右键——运行单元测试
2.测试控制器
在测试项目中,需要引用ASP.NET MVC框架和HomeController类的名称空间,即
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using T10.Controllers;
using System.Web.Mvc;
namespace UnitTestProject1
{
//单元测试类
[TestClass]
public class UnitTest1
{
//测试方法
[TestMethod]
public void TestMethod2()
{
//测试HomeController的Index()方法是否返回ViewResult类型
HomeController c = new HomeController();
var result = c.Index();
Assert.IsInstanceOfType(result, typeof(ViewResult));
}
[TestMethod]
public void TestMethod3()
{
//测试HomeController的Contact()方法是否返回ViewBig值是否和预期结果相同
HomeController c = new HomeController();
ViewResult result=c.Contact() as ViewResult;
Assert.AreEqual("Your contact page.", result.ViewBag.Message);
}
}
}
3.安装和配置IIS
3.1.1.IIS功能可以通过“控制面板”中“启用或关闭Windows功能”进行安装
3.1.1.1.方法一
打开控制面板——切换查看方式为程序查看——选中启用或关闭Windows功能
3.1.1.2.方法二
打开控制面板——切换查看方式为大小图标——选择程序和功能——选中启用或关闭Windows功能
3.1.2.打开启用或关闭Windows功能后,至少选中InternetInformation Services选项以及“应用程序开发功能”选项中的“ASP.NET 4.7”,才更正常运行ASP.NET相关网站
3.1.3.勾选完成,点击确认,等待安装完成后重启电脑即可
4.Web程序发布
Web应用程序通过Visual Studio一键式发布至IIS中