概述
MVC设计模式->MVC框架(前端开发框架),asp.net(webform) aspx
M:Model (模型,负责业务逻辑处理,比如说去db中获取数据)
V:View (视图,负责展示页面元素给用户,Razor模板(.cshtml) 由Razor引擎读取.cshtml将里面的占位符根据Razor的语法结构一一替换成html代码)
C:Controller (控制器,负责根据url请求路径,决定调用哪个action)
2、Razor引擎对应的页面扩展名为:.cshtml
2.1、在.cshtml引用命名空间的指令为:@using
2.2、cshtml页面本质上会被编译成一个前台页面类,继成WebViewPage 类 (弱类型视图)
2.3、强类型视图:
1、在cshtml页面上使用指令@model 要转换的类型,就将当前cshtml视图变成了指定的强类型视图
2、在当前视图所对应的action中要通过 View()方法传入对于的实体数据
3、MVC重要的特点:约定大于配置
1约定
控制器约定:
1、控制器的后缀名一定是Controller结尾
2、方法控制器下的方法会去查询其Views文件夹下的和控制器同名目录下的和action同名的视图
3、控制器中的action方法一定是public,否则会抛出404异常
action向视图传值的方式:
1、ViewData
2、ViewBag
3、TempData
4、View() :通过Model传递给视图页面的 ,所以在.cshtml中是用Model来接收的
注意点; ViewBag 本质上使用的是ViewData来传递的,所以ViewBag和ViewData存在相同key,那么后面那个的值会覆盖前面那个的值
二、传值
在控制器的方法中接收url传值id的方式:
1、Request.QueryString[]
2、Request.Params[]
3、通过路由规则参数 占位符
约定:action方法中的形参 名称一定要和匹配路由规则的占位符{id}保持一致
三、可以在View()方法中由程序员指定要返回的视图名称
例如: return View(“Index1”); //视图引擎一定是去和当前action所在控制器同名的文件夹中查找Index1.cshtml视图返回
、控制器重要约定
1、控制器类名称后面一定是要以Controller 结尾,父类必须继承Controller
2、控制器中的actin所对应的视图页面,是存放在Views文件夹下和控制器同名的文件下
3、在action 中通过return view() :告诉视图引擎去当前Views文件夹下查找和action 方法同名的视图文件
4、return view(“程序员可以自己指定视图名称”)
5、路由:
5.1、当MVC应用程序第一次启动的时候,就会执行Global.asax文件中的Application_Start()方法
调用RouteConfig.RegisterRoutes()注册好程序员编写的路由规则
5.2、路由规则的主要作用:1、mvc.net会根据路由规则中的url来解析 当前浏览器发出的请求路径中,哪段文本表示控制器
哪段文本表示action 例如: /Home/Index
6 action方法的结构:
1、action方法必须是public的方法,否则会出现找不到
2、方法的返回类型可以是actionResult也可以是string,void等
3、为什么return view()可以满足ActionResult的返回值要求呢? 是因为 View()本质是一个ViewResult 类型,而ViewResult 继成ActionResult
4、action如何将数据传入视图?
1.0 通过 ViewData[“name”]给视图传值 ViewData[“name”] = “八戒”;
2.0 ViewBag 给视图传值 ViewBag.Age = 500; 本质上ViewBag 的设置和赋值都是操作的ViewData
3.0 TempData[“Name”] 给视图传值 TempData[“Name”] = “八戒11”;
4.0 通过View()指定返回的实体
Person person= new Person() { Name = “汉尼拔”, Age = 10 };
return View(person);
7、 HttpGet,HttpPost特性
如果一个方法标记了HttpGet 特性,则该方法只负责处理get请求
如果一个方法标记了HttpPost特性 特性,则该方法只负责处理Post请求
8、ActionResult子类演示
8.1、ViewResult() -->action方法中要想返回视图,则要使用ViewResult (MVC开发中用的最多)
8.2、ContentResult() -->返回内容之用(特点,可以不需要有对应的视图)
8.3、JsonResult() -->HomeController 的JsonDemo() 可以用作ajax请求 ,注意:如果是get请求,则一定是要在Json()中写入:JsonRequestBehavior.AllowGet
8.4、FileResult() -->HomeController 的FileResultDemo() 可以用作画验证码,也可以利用它来实现文件的下载
8.5、HttpStatusCodeResult() --》用户自己设置需要响应的状态码
8.6、JavaScriptResult 注意:JavaScript配合视图中的
注意:9、Server.Transfer()跳转只能跳转到aspx页面,不能跳转到.ashx文件,在MVC使用Server.Transfer("/Home/Index") 也会报错
一、从action中返回指定的视图
return View(): 去当前action所在的控制器同名的views下的文件中查找和action同名的视图
return view(“targetview2”):去当前action所在的控制器同名的views下的文件中查找指定的targetview2 的视图
return View("~/Views/Test/Index.cshtml"); 去指定的目录中查找视图
二、_viewstart.cshtm ,_layout.cshtml:
_viewstart.cshtm:
1、如果当前_viewstart.cshtm处在views下面的,那么当前views所有的视图被访问的时候,都会先执行_viewstart.cshtm
2、如果在某个目录Home下也存在一个_viewstart.cshtm,那么会先执行views跟目录下的_viewstart.cshtm中的内容,再执行Home目录下的_viewstart.cshtm中的内容
_layout.cshtml:
作用:给整个网站进行风格定位,如果子页面使用了此_layout.cshtml,那么它的样式则就是_layout.cshtml中的样式
作用相当于asp.net中的母板页(.master)
@RenderBody():作用:RenderBody仅仅只是当前布局页中的占位符,它会被子页面中的内容替换,@RenderBody() 只能在layout中出现一次
@Styles.Render("/Content/css"):作用,会根据虚拟路径"/Content/css" 来找到该虚拟路径下注册好的所有css文件响应给浏览器
@Scripts.Render("/bundles/jquery")作用,会根据虚拟路径"/bundles/jquery" 来找到该虚拟路径下注册好的所有js文件响应给浏览器
注意:要正常使用@Styles.Render()和@Scripts.Render() 的必要条件,必须在程序启动的时候,必须执行Global.asax 文件中的
BundleConfig.RegisterBundles(BundleTable.Bundles);代码 ,作用是 将类似于"~/Content/css"的虚拟路径和其物理文件做一一映射,否则不能使用
原因:1、自动压缩js和css的文件大小 2、方便程序来开发导入到视图页面
@RenderSection(“scripts”, required: false) 作用:
RenderSection 所定义的标签,可以被子页面重写,如果required设置成true,则必须子页面重写,如果是false可以不重写也可以重写
Razor语法小结:
Razor视图:
扩展名:.cshtml
@:Razor 语法 ,在@{}中所写的代码都是c#代码
例如:
div>
输出html文本
@{
string astr = “ 导航到baidu”;
//1.0 利用 Html.Raw ()方法来正常输出html标签
@Html.Raw(astr)
//2.0 利用 MvcHtmlString来正常输出html标签
MvcHtmlString mvcstring = new MvcHtmlString(astr);
@mvcstring
@mvcstring.ToHtmlString()
//3.0 利用 HtmlString来正常输出html标签
HtmlString htmlstring = new HtmlString(astr);
@htmlstring
@htmlstring.ToHtmlString()
}
<hr />
@@astr=
@{
//4.0 @: astr 作用:会将@:后面的变量 当做字符串输出
,注意:@:只能写到@{} 花括号中
//4.0.1 @表示转义符
输出@astr到网页则必须写:@@astr ,只能
@{} 花括号外
@:astr;
//4.0.2 <text><text>
将包括在其中的变量当做字符串输出,而不是输出变量的值,<text></text>只能写在@{} 花括号中
<text>astr</text>
}
<hr />
<span style="font-size: 16px; color: blue;">5.0 调用有返回值的方法:</span>
@{
string res = MVC.Site.helper.Kits.GetValue("你好");
@res
}
<br />
5.0.1 直接使用@@符号即可输出
<br />
@MVC.Site.helper.Kits.GetValue("你好啊")
<br />
Response.Write()输出 :如果使用@@来调用无返回值的方法则必须将其放入{}中
@{Response.Write(MVC.Site.helper.Kits.GetValue("你好啊11"));}
<br />
<hr />
6.0 调用泛型方法
@{
//调用泛型方法获取返回值赋值给resint
int resint = MVC.Site.helper.Kits.GetTResult<int>(100);
//输出结果到屏幕:
@resint
}
<br />
6.0.1
直接使用@@()
来调用泛型方法
@(MVC.Site.helper.Kits.GetTResult<decimal>(12.38m))
<hr />
操作web上下文中的相关对象
@HttpContext.Current<br />
@Response<br />
@@Request.QueryString["id"]=
@Request.QueryString["id"]<br />
@Server<br />
@Session<br />
@Cache<br />
@HttpContext.Current.Server.GetLastError() //gloabl.asmx中的Application_Error()收集当前没有try{}catch{}的异常信息
<hr />
7.0 数据类型转换相关扩展方法<br />
@("123a".AsInt())
等价于
@@{ int.TryParse()}
@("123".IsInt())
结果:true
@("123.4".AsDecimal())
@("123.4".IsDecimal())
<hr />
8.0 @@后面有空格的语境
<span>JamesZou@Itcast.us</span>
<br />
当@后面有空格的时候 后面的文本会当做变量使用
<span>JamesZou@@ Itcast.us</span>
<br />
<hr />
9.0 路径转换 "~/home/index"
@@Href("~/home/index")
= @Href("~/home/index")
<hr />
10.0 可以在Razor视图中自己定义方法供Razor调用
@helper
CreateH2(int num)
{
for (int i = 0; i < num; i++)
{
@i
}
}
@CreateH2(5)
</div>
二、HtmlHelper类中的扩展方法
@Html.TextBoxFor(c => c.Name, new { @class=“red” })
@Html.DropDownListFor(c => c.GroupId, ViewData[“slist”] as SelectList)
@Html.CheckBoxFor(c=>c.IsKill)
@Html.TextAreaFor(c=>c.Name)
@Html.TextBox(“id1”, Model.ID, new { @class = “green”, style = “font-size:18px” });
@Html.DropDownList(“gid”, ViewData[“slist”] as SelectList)
@Html.CheckBox(“IsKill”, Model.IsKill);
@Html.Hidden(“ID”, Model.ID)
@Html.ListBox(“type”, ViewData[“slist”] as SelectList)
@Html.RadioButton(“type1”, “1”, true)
@Html.RadioButton(“type1”, “2”, false)
三、 模型注解(特性) 和 非侵入式脚本(fromvalidate.js) (配合使用可以实现页面前端控件值的验证(非空验证,输入值的合法性验证))
注解:就是往实现属性上添加特性:Required,StringLength等。。。
1、模型实体属性注解
Required特性:可以实现对视图页面上对应的模型中属性文本框进行非空验证
StringLength:约束属性值的长度
DisplayName:在视图上可以利用 @Html.DisplayName() @Html.DisplayNameFor (),@Html.LabelFor 来显示具体的值 (演示在c10/Index)下
Compare:将当前附加了此特性的属性值与目标属性值比对,如果不相等则不通过并且提示给用户(在用户注册页面的 确认密码的时候可以使用)
RegularExpression:可以由程序员自由编写正则表达式来对属性值进行约束
DataType:标示附加的类型
Remote:通过在属性上添加Remote特性,可以实现对当前属性值的内容进行重复性检查 ,Remote 是通过ajax请求来进行验证的,为了防止缓存一般写成post请求(位于System.Web.Mvc命名空间下)
例如写法:
[Remote(“Check”, “Home”, ErrorMessage = “当前猫的名称已经被注册,请重写换一个”,HttpMethod=“post”)]
public string Name { get; set; }
Remote必须有一个action来配合它的使用,如果action中返回的值为 false,则表示当前文本框中的值已经存在,否则可以使用 true
public ActionResult Check()
{
//1.0 先获取remot发送给check的参数Name的值
string name = Request.Form[“Name”];
if (name == “ZPP”)
{
return Content(“false”);
}
else
{
return Content(“true”);
}
}
Rang: 可以约束int型等类型的数值范围
要能够正常进行非空等合法性验证必须做如下步骤:
1、必须在实体的每个string类型的属性上加上Required特性
2、必须在视图上导入如下脚本:
1、 @非侵入式js脚本@
3、将web.config中的 节点中的ClientValidationEnabled 设置成true 才能实现客户端的验证
4、必须是在做post提交的时候此验证才有效
4、视图上的控件必须使用:
@Html.TextBox(“Name”) 或者@Html.TextBoxFor(“Name”) 来显示
@Html.ValidationMessage(“Name”)作用:当文本框输入的值不合法的时候,提示语句就是用@Html.ValidationMessage(“Name”) 来显示给用户
1、在实体模型属性上添加 DataType
DataType:表示附加的类型
@Html.Editor()方法
实例写法:
public class DataTypePig
{
[DataType(System.ComponentModel.DataAnnotations.DataType.Text)]
public string Name { get; set; }
[DataType(System.ComponentModel.DataAnnotations.DataType.Password)]
public string Pwd { get; set; }
[DataType(System.ComponentModel.DataAnnotations.DataType.PhoneNumber)]
public string Phone { get; set; }
public bool isKill { get; set; }
public int Age { get; set; }
}
在视图上使用@Html.EditorFor()泛型方法来自动根据DataType的类型决定生成什么样的html标签
2、分部视图
分部视图是什么:类似于asp.net webform (aspx)中的用户自定义控件 .ascx
作用:可以将相同的逻辑块写到分部视图中,供其他视图来使用@Html.Partial()来调用
@Html.Partial(“Index”, new MVC.Site.Pig() { Name=“八戒” }):
方法的参数1 :表示请求当前控制器的下Index方法
参数1:向分部视图传入Model实体
Server.Execute();
请求分部视图的方式1:
@Html.Partial(“Index”, new MVC.Site.Pig() { Name = “八戒” })
<hr />
请求分部视图的方式2:<br />
@{Html.RenderPartial("Index", new MVC.Site.Pig() { Name = "八戒" });}
<hr />
请求分部视图的方式3:<br />
@{Html.RenderAction("Index", new { controller = "C14PartalView" });}
<hr />
请求另外一个验证码的action 类似于asp.net中的服务器包含 Server.Execute()
@{Html.RenderAction("View1", "C01");}
扩展:
return PartialView();与 return View();区别
1、return PartialView()不会执行views目录下的_ViewStart.cshtml,而return View() 会执行views目录下的_ViewStart.cshtml
3、在控制器的action中进行参数合法性验证
重点:由于用户可以将浏览器的js脚本禁用,那么就会导致网站的非侵入式验证脚本失效
所以,除了在客户端进行合法性验证外还应该在action方法中进行服务器端的验证:
代码写法步骤:
1、在action方法体第一步加入 if (ModelState.IsValid == false) //表示验证不通过,将信息返回给视图
2、可以利用 ModelState.AddModelError("", ex.ToString()); 追加自定义提示信息
3、在视图可以 利用@Html.ValidationSummary(false); 将程序员自定义的异常提示信息给用户,如果是true,则将非侵入式验证脚本验证(属性的验证信息)的错误信息也显示出来
3、@Url中的扩展方法
@Url.Action():会根据当前网站路由规则的占位符自动生成url
@Url.Content():仅仅只是将~去掉
4、@Ajax中的扩展方法
@Ajax.ActionLink()
@Ajax.BeginForm()
@Ajax.BeginRouteForm():告诉MVC是当前url是根据哪个路由规则生成的
二、AjaxHelper中扩展方法
2.1、ajax.actionLink()方法可以生成异步请求的标签
使用步骤:
1、必须添加如下两个脚本
2、利用@Ajax.ActionLink()方法生成标签,ActionLink方法会自动在标签上添加 data-ajax=“true” 的属性,data-ajax=“true” 可以被jquery.unobtrusive-ajax.js
读取执行异步请求,请求的url为 标签上的属性 href 中的值
写法实例:
@Ajax.ActionLink(“获取服务器时间”, “GetServerTime”, new { controller = “Ajax” }, new AjaxOptions()
{
HttpMethod = “get”,
OnSuccess = “sucuess”,
OnBegin = “begin”,
OnComplete = “comp”,
OnFailure = “failure”,
Confirm = “您确认请求吗?”,
InsertionMode = InsertionMode.Replace, //InsertionMode.Replace:将最后的响应结果替换UpdateTargetId 所对应的dom元素中的内容
//InsertionMode.InsertAfter:将最后的响应结果插入到UpdateTargetId 所对应的dom元素中的内容 之后
//InsertionMode.InsertBefore:将最后的响应结果插入到UpdateTargetId 所对应的dom元素中的内容 之前
UpdateTargetId = “result”, // 可以设置服务器响应回来的数据到指定id的dom元素中
LoadingElementId = “lbloding”,
LoadingElementDuration = 10000
})
2.2 利用Ajax的BeginForm 方法可以异步提交表单
写法实例:
@using (Ajax.BeginForm(new AjaxOptions() { HttpMethod = “post”, InsertionMode = InsertionMode.Replace, UpdateTargetId = “displayResult”, OnSuccess = “sucess”, OnBegin = “begin”, OnComplete = “comp”, OnFailure = “failure”, Url = Url.Action(“PostSumbmit”, “AjaxBeginForm”) }))
{
@Html.DisplayNameFor(c => c.Name):
@Html.TextBoxFor(c => c.Name)
@Html.ValidationMessageFor(c => c.Name)
@Html.DisplayNameFor(c => c.Age)
@Html.TextBoxFor(c => c.Age)
@Html.DisplayNameFor(c => c.Gender)
@Html.CheckBoxFor(c => c.Gender)
<input type="submit" value="提交" />
}
其中OnSuccess 回调函数中的参数值分为如下2中:
1、如果响应报文头中的Content-Type为text/html 则参数值直接为响应报文体中的文本数据
2、如果响应报文头中的Content-Type为application/json 则参数值会是已经将json字符串转换好的js对象
非侵入式脚本可以在web.config中进行全局控制
以上表示开启所有页面的非侵入式脚本
以下两个脚本表示关闭所有页面的非侵入式脚本
也可以在某个视图页面手动关闭非侵入式脚本
div>
@{
//关闭当前add.cshtml页面上所有的非侵入式(非介入式)脚本
Html.EnableUnobtrusiveJavaScript(false);}
@{
//关闭当前add.cshtml页面上的参数合法性验证
Html.EnableClientValidation(false);
}
一、路由规则及约束
路由约束之一:参数类型约束
1、RouteDebugger.dll的作用:
可以在当前请求的页面上打印出当前url所匹配的路由规则有哪些?并且告诉用户当前url使用的路由规则是哪条
2、RouteDebugger.dll的用法
2.1、在当前MVC项目中引用RouteDebugger.dll
2.2、在当前mvc项目中的web.config的几点中添加:
<add key="RouteDebugger:Enabled" value="true" />
3、
* 注意点:
* 1、如果有多条路由规则的时候,要保证每个路由规则的名字不同
* 2、如果一个url匹配成功了多条路由规则,则以最前面的那条为准(匹配成功的第一条路由规则为准)
4、
/*可以匹配Default 路由规则的url有:
*1、 http://localhost/Home/Index
*2、 http://localhost/Home/Index/100
*/
routes.MapRoute(
name: “Default”, //路由规则的名称
url: “{controller}/{action}/{id}”, //路由规则的正则表达式(url的占位符)
defaults: //设置url的占位符中{controller},{action},{id}的默认值
new
{
controller = “Home” //当前给controller设置的是默认去访问home控制器
,
action = “Index”// 默认去访问home控制器中Index 方法
,
id = UrlParameter.Optional //表示设置当前id参数为可选参数
}
, constraints: //constraints:给路由规则添加约束
new
{
id = “d+” //约束当前Default路由规则的匹配id参数只能是数字
}
, namespaces: new string[] { “ControllerA” } //作用:如果指定了namespaces 则当url匹配成功此路由规则后,
//自动去程序员指定的namespaces中查找相应的控制器,
//好处:1、隔离不同程序员写的控制器 2、当url匹配到此规则时,只会去程序员指定的namespaces中查找相应的控制器,大大提高了反射时的扫描效率
);
路由约束之二:命名空间约束
写法:
routes.MapRoute(
name: “Default”,
url: “itcast/{controller}/{action}/{id}”,
defaults: new { controller = “Home”, action = “Index”, id = UrlParameter.Optional }
, constraints: new { id = “d+” } //约束id只能是数字
, namespaces: new string[] { “MVC路由约束.Controllers” }
);
好处:1、可以自动去MVC站点的bin目录查找指定命名空间下的控制器类,大大节省了查找时间,效率更优
2、方便同一个路由规则在不同控制器之间的切换
//由于mvc中有aspx和razor两套视图引擎,并且排序为:1、aspx视图引擎,2、Razor引擎
//所以我们只要移除0索引处的元素即可
ViewEngines.Engines.RemoveAt(0);
二、区域(Areas)
注意点:1、所有的区域必须放在mvc主站点的 Areas文件夹下 (插件开发)
2、每个区域下都要有个一个继承了AreaRegistration 父类的子类,并且在子类中要重写如下两个:
1、区域名称
public override string AreaName
{
get
{
return “OnlinePay”;
}
}
2、当前区域的路由规则注册方法(作用:负责注册当前区域下的所有路由规则的)
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
“OnlinePay_default”,
“OnlinePay/{controller}/{action}/{id}”,
new { action = “Index”, id = UrlParameter.Optional }
//参数约束
//命名空间约束
);
}
三、MVC中的相关过滤器
3.1 、action过滤器 (方法过滤器) 和result过滤器 (结果过滤器)
应用:一般用于【统一登录验证】和【权限验证】 一般写在OnActionExecuting()方法中
作用:类A必须要继成ActionFilterAttribute,并且重写里面的
OnActionExecuting():在action()方法的逻辑执行之前会先执行OnActionExecuting()中的逻辑
和OnActionExecuted:在action()方法的逻辑执行之后会执行OnActionExecuted()中的逻辑
action过滤器用法步骤:
1、自己定义一个继成了类ActionFilterAttribute的自定类名字叫做ActionFilterAttribute1
2、在App_Start/FilterConfig.cs文件中的public static void RegisterGlobalFilters(GlobalFilterCollection filters) 方法中
添加自定义过滤器的注册代码: filters.Add(new ActionFilterAttribute1());
3、自定义过滤器如果没有在FilterConfig.cs中进行全局注册,则可以在某个action方法上添加特性标签
例如
[MVCFilter.Filters.ActionFilterAttribute1]
public ActionResult Index()
{
Response.Write(“这是Index()方法中输出的文本
”);
return View();
}
4、如果想在控制器Home中的所有方法都能够被自定义过滤器切入
3.2、AuthorizeAttribute 验证过滤器
特点:在action过滤器运行前执行
注意:在重写的过程中如果执行了base.OnAuthorization(filterContext); 则会跳转到登录页面
解决方法有两个:
1、在action上贴上[AllowAnonymous] 特性标签
2、在过滤器重写的OnAuthorization方法中不调用base.OnAuthorization(filterContext);
例如:
public override void OnAuthorization(AuthorizationContext filterContext)
{
filterContext.HttpContext.Response.Write("----这是OnAuthorization–输出的
");
//base.OnAuthorization(filterContext); //注意此处有注释掉所以不会转到登录页面
}
3.3、HandleErrorAttribute 异常捕获过滤器
特点:可以统一捕获当前MVC网站中的异常信息
一、统一跳转到error.cshtml 的系统配置
1、如果实现了全局异常过滤器HandleErrorAttribute
a) 请将 filterContext.ExceptionHandled 设置成 false 写法: filterContext.ExceptionHandled = false;
b)在mvc网站的跟目录下的 web.config 中 <system.web> 节点中添加
c)将Views/Shared/Error.cshtml 指定为 @model HandleErrorInfo
二、webapi
1、webapi的路由规则注册在App_StartWebApiConfig.cs文件中
2、webapi控制器继承父类 apiController
3、调用webapi的方式:
get请求http://localhost/api/home/1 则默认请求 Home控制器下的Get方法将1作为get()方法的参数
Post请求http://localhost/api/home/1 则默认请求 Home控制器下的Post方法将1作为Post()方法的参数
4、将webapi默认的返回格式设置成json格式写法
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//将webapi中的XmlFormatter 移除,默认就是以JsonFormatter作为其传输格式
config.Formatters.Remove(config.Formatters.XmlFormatter);
}
最后
以上就是不安白开水为你收集整理的MVC的全部内容,希望文章能够帮你解决MVC所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复