MVC5入门学习
??
一、概述MVC简介:? 模型(Model) “数据模型”(Model)用于封装与应用程序的业务逻辑相关的数据以及对数据的处理方法。“模型”有对数据直接访问的权力,例如对数据库的访问。“模型”不依赖“视图”和“控制器”,也就是说,模型不关心它会被如何显示或是如何被操作。但是模型中数据的变化一般会通过一种刷新机制被公布。为了实现这种机制,那些用于监视此模型的视图必须事先在此模型上注册,从而,视图可以了解在数据模型上发生的改变。 ? 视图(View) 视图层能够实现数据有目的的显示(理论上,这不是必需的)。在视图中一般没有程序上的逻辑。为了实现视图上的刷新功能,视图需要访问它监视的数据模型(Model),因此应该事先在被它监视的数据那里注册。 ? 控制器(Controller) 控制器起到不同层面间的组织作用,用于控制应用程序的流程。它处理事件并作出响应。“事件”包括用户的行为和数据模型上的改变。 ? MVC网站的访问流程:? 1. 当第一个请求从客户端发起的时候,首先执行的是Global.asax中的Application_Start()方法来完成一些初始化工作,其中重要的一步是RegisterRoutes方法,这个方法指定了如何将url映射到具体的方法上,稍后详解。 ? 2. 根据第一步中指定的映射表生成一个RouteData对象,利用这个对象来创建一个RequestContext对象。 ? 3. MvcRouteHandler创建一个MvcHandler,并将RequestContext对象传给MvcHandler。 ? 4. MvcHandler对象利用RequestContext对象确定一个IControllerFactory对象来创建Controller对象。 ? 5. MvcHandler对象调用Controller对象的Execute()方法。 ? 6. Controller的ControolerActionInvoker对象决定调用controller的哪个具体的action方法。 ? 7. Action方法接受用户参数,执行方法,返回一个Result类型的对象。 二、MODEL定义使用@model关键字可以定义一个Action里所对应的一个模型(经常可以叫他实体类), 其实是对动态变量进行实例化,这样就可以直接在cshtml文件中调用“Model”变量。 而这个模型的实例,需要通过Controller进行传输,如果没有则“Model”将为null。 模型可以是一个实体类,也可以是一个列表实例,字典对象都可以进行定义,但是和 Controller中的Action传回来的实例一定要一样,否则将会出现错误。例如我们获取 用户实例,并且在页面上呈现用户的具体信息,这样就可以将用户实例返回给前台 验证标记模型的定义及验证标记如下示例: 验证标记整理:Model类中可以添加的验证标记: 1. 必填字段 [Required] public string FirstName { get; set; } 2. 字段长度 至多n位: [StringLength(160)] public string FirstName { get; set; } 要求至少n位: [StringLength(160,MinimumLength=3)] public string FirstName { get; set; } 3. 正则验证 [RegularExpression(@”[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}”)] public string Email { get; set; } 4. 范围 [Range(35,44)] public int Age { get; set; } 小数的情况: [Range(typeof(decimal),“0.00”,“49.99”)] public decimal Price { get; set; } 5. 服务端参与的验证 [Remote(“CheckUserName”,“Account”)] public string UserName { get; set; } 然后在AccountController里指定一个CheckUserName方法: public JsonResult CheckUserName(stringusername) { var result = Membership.FindUsersByName(username).Count == 0; return Json(result,JsonRequestBehavior.AllowGet); } 6. 比较 [RegularExpression(@”[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}”)] public string Email { get; set; } [Compare(“Email”)] public string EmailConfirm { get; set; } 7. 自定义错误消息 正则: [RegularExpression(@”[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+.[A-Za-z]{2,4}”, ErrorMessage=”Email doesn’tlook like a valid email address.”)] public string Email { get; set; } 普通文本: [Required(ErrorMessage=”Your last name isrequired”)] [StringLength(160,ErrorMessage=”Your lastname is too long”)] public string LastName { get; set; } 占位符: [Required(ErrorMessage=”Your {0} isrequired.”)] [StringLength(160,ErrorMessage=”{0} is toolong.”)] public string LastName { get; set; } 三、View与Controller1、母版页Shared/_Layout.cshtml 2、HtmlHelperActionLink @Html.ActionLink("Text","Index","Home",new{page=1},new{id="link1"}) 解释为: <ahref="/?page=1"id="link1">Text</a> RouteLink 其实就是用一个新建立的RouteValueDictionary的对象(new{}所实例化的对象将会等价转换为RouteValueDictionary)来替原来的Action,Controller字符串的单独指定。 示例:@Html.RouteLink("Text",new { action = "index",page = 1 },new { id="link1"}) 可通过路由名称指定指向某路由路径。 示例:@Html.RouteLink("关于","about",new { page = 1 },new { id = "link1" }) 其中about为路由名称 表单 表单两种方式: 1、<form action="@Url.Action("Index","Home")"method="post"></form> 2、@using(Html.BeginForm("Index","Movies",FormMethod.Get)){} 3、绑定下拉框示例: @Html.DropDownList("movieGenre","All") 3、urlHtml<a href='<%=Url.Action("DemoAction","DemoController",new{id=2,category=5 },"https")%>' title="">指定传输协议生成URL</a><br/> 解释为:<ahref='https://localhost/DemoController/DemoAction?id=2&category=5'title="">指定传输协议生成URL</a><br /> 4、Controller从Model获取数据,然后通过ViewData传递给View数据 可以使用不同的View呈现数据 ActionResult的其它返回值:JsonResult、RedirectResult PartialView(自定义控件)、View方法 ViewData、TempData传值 ViewData只能在当前Action中有效 TempData可以类似于Session一样到其它页面仍然存在,但只限一页的访问 TempData一般用于临时的缓存内容或抛出错误页面时传递错误信息 绑定View表单下拉框示例: 5、验证ValidateAntiForgeryToken 特性,这个特性用来阻止伪造的请求,它和视图(ViewsMoviesEdit.cshtml)中的@Html.AntiForgeryToken() 是成对出现的。 显示验证错误信息 @Html.ValidationSummary(true,"",new { @class = "text-danger" }) 6、ajax提交1、显示当前页面层 2、提交数据到controller中方法如下图代码 3、ajaxHelper 1、Ajax异步请求ContentController ContentController直接以字符串形式返回实例的内容,在Index.cshtml中使用ActionLink,如下: @Ajax.ActionLink("AjaxContentController","getEntry",new { id = item.Id },new AjaxOptions { HttpMethod ="Post",UpdateTargetId = "detailsID",InsertionMode =InsertionMode.Replace }) 相应的Controller: public string getEntry(int id = 0) { GuestbookEntryentry = _db.Entries.First(c => c.Id == id); returnentry.Details; } 2、使用Json格式返回 @Ajax.ActionLink("AjaxJsonController","JsonDetails",InsertionMode = InsertionMode.Replace,OnSuccess = "Show();"}) 相应的Controller: public ActionResult JsonDetails(int id = 0) { GuestbookEntryentry = _db.Entries.First(c => c.Id == id); return Json(entry,JsonRequestBehavior.AllowGet); } 注意:在使用Json格式返回数据时,由于安全原因,只接收Post请求,因此在这里使用JsonRequestBehavior.AllowGet来允许Get方式请求。 同时需要在Index.cshtml中添加请求成功的相应函数Show: <script type="text/javascript"> function Show(data) { $("#detailsID").html("姓名:" + data.Name+ " 消息:" + data.Message); } </script> 四、路由配置路由配置:1、多个区域中增加多个member,而每个member中存在一个路由 2、在项目中可以设置一个总路由指定到某个命名空间。然后在每个member区域设置单独路由。 MapRoute是RouteCollection的扩展方法,同时还有IngnoreRoute,而Add则是实例方法,相对来说要使用Add来调用比较复杂(包含刚才提到的5大属性),而MapRoute则相对简洁。 Add routes.Add(new Route("blog/{action}/{author}",
new RouteValueDictionary { {"action","show" },{"author","miracle"} },
new MvcRouteHandler()));
MapRoute
routes.MapRoute( "Article",// 路由名称 "blog/{action}/{author}",51)">带有参数的 URL new { controller = "Home",action = "show",author = "miracle" }
); 路由解析处理:当用户输入URL地址发送请求时,UrlRoutingModule类就会到路由表(RouteTable)中解析与请求匹配的路由,然后将该路由分发到路由处理程序(IRouteHandler),并连同RequestContext一起再次分发到Mvc处理程序(IHttpHandler),定位相关的控制器并执行相关的动作实现输出。以下的整个过程的示意图。 在传统的Web站点中使用路由(一般情况下用户将传统站点转化为MVC站点的项目迁移过渡)。主要包含以下两个步骤: 1、常见实现IRouteHandler接口的WebFormRouteHandler类,返回实现IHttpHandler接口的实例化对象实际上任何一个Page都是一个实例对象。 public class WebFormRouteHandler : IRouteHandler { public stringVirtualPath { get; private set; } //初始化虚拟路径 publicWebFormRouteHandler(string virtualPath) { this.VirtualPath= virtualPath; } public IHttpHandler GetHttpHandler(RequestContext requestContext) { 创建实例化的页面对象 var page =BuildManager.CreateInstanceFromVirtualPath(VirtualPath,typeof(Page)) as IHttpHandler; return page; } } 2配置全局应用程序类(Global.asax),实现路由的映射。 routes.MapMvcAttributeRoutes(); //Attribute路由注册 AreaRegistration.RegisterAllAreas();//区域路由注册 注:增加区域之后,防止路由重复,需在默认路由中为命名空间赋值。 Attribute路由1、路由定义和 Action 放在一起:[Route("Home/Index/{id}")] public ActionResult Index() {... } 与通用路由是否可以一起使用待验证,已经验证,可以一起使用。以Attribute这里为主。 2、可选参数和默认值[Route("Home/Index/{id?}")] 匹配//Home/Index或者/Home/Index/id //匹配:/books/lang //匹配:/books/lang/en //匹配:/books/lang/he //如果URL不传递 lang 参数,则lang的值为“en” [Route("books/lang/{lang=en}")] 3、前缀//匹配:/Home [Route("Home")] publicActionResult Index() { ... } //匹配:/ Home/5 [Route("Home/{id}")] publicActionResult Show(int id) { ... } //匹配:/ Home/5/edit [Route("Home/{id}/edit")] publicActionResult Edit(int id) { ... } 或者在controller前面增加属性[RoutePrefix("Home")]
4、默认路由
[RoutePrefix("promotions")] [Route("{action=index}")] 默认promotions,action为index
ActionResult前面增加[Route]则覆盖默认路由。
5、路由约束路由约束可以让你指定参数的类型以及范围等,格式为:{参数:约束},举例如下: // 匹配: /users/5 [Route("users/{id:int}"] 这里约束了参数“id”必须为整数类型
publicActionResult GetUserById(int id) { ... } 下面是支持的路由约束列表:
你可以在一个参数后面应用多个约束,用冒号分隔它们,如下: 但是不匹配 /users/10000000000因为的值已经超过了int.MaxValue, 也不匹配 /users/0因为后面有个min(1)约束,的值必须大于等于 1. [Route("users/{id:int:min(1)}")]
6、自定义约束看上例
7、路由名称[Route("menu",Name = "mainmenu")] publicActionResult MainMenu() { ... } 可以使用Url.RouteUrl来生成相应的 URL: <ahref="@Url.RouteUrl("mainmenu")">Main menu</a> 8Areas区域Area概念对组织大型Web应用程序很有帮助,在Attribute路由中当然少不了对它的支持,只要使用 [RouteArea],就可以把 Controller 归属到某一个 Area 下 删除Area 下的AreaRegistration 类 [RouteArea("Admin")] [RoutePrefix("menu")] [Route("{action}")] publicclass MenuController : Controller { //匹配:/admin/menu/login publicActionResult Login() { ... } } 五、扩展1、实现对HTMLHelper的扩展。新建文件夹:Extensions,文件夹Extensions中添加自定义扩展。 使用时,view页面必须加入:@using MVCMovie.Extensions;//自定义。 页面引用如:@Html.QINLabel("male","男") 示例: public static string Label(this HtmlHelperhelper,string name,string value) { return string.Format("<labelfor='{0}'>{1}</label><br />",name,value); } 2、AjaxHelper的扩展新增扩展类 控制器 public class AjaxHelperExtController :Controller { // // GET: /AjaxHelperExt/ public ActionResult AjaxHelperExt() { return View(); } public ActionResult GetTime() { return Content("Now Time:" + DateTime.Now.ToString()); } } 最后在jquery.unobtrusive-ajax.js里面加上TextBox的Keyup事件绑定 $("input[type=text][data-ajax=true]").live("keyup",function (evt) { asyncRequest(this,{ type: "GET",data: [{ name:$(this).attr('name'),value: $(this).val()}] }); }); 调用 <divid="divTime"></div> @Ajax.Textbox("search", new AjaxOptions { Url = @Url.Action("GetTime"), UpdateTargetId = "divTime", InsertionMode = InsertionMode.Replace }, new { size = 50 }) 注:同时需要在页面中引入MicrosoftAjax.js,MicrosoftMvcAjax.js 在web.config中增加client side validation and unobtrusive javascript 两个配置 <addkey="ClientValidationEnabled" value="true" /> <addkey="UnobtrusiveJavaScriptEnabled" value="true" /> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |