Asp.Net MVC基础
一、Application_Start
想着记录一下MVC的一些基础知识,但是感觉比较杂乱,那就从启动开始吧。我们启动一个MVC项目时,响应第一次请求的是Global.asax.cs文件中的Application_Start方法。我们先来看下它里面做了什么事情。
protected void Application_Start() { AreaRegistration.RegisterAllAreas();//注册区域路由 GlobalConfiguration.Configure(WebApiConfig.Register);//注册webapi路由 FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);// RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
该方法执行了一些初始化的工作,注册Route, Filter, Bundle。Route之前的文章已经有讲过,Filter后面再专门讲。那么Bundle是做什么的呢。它是添加了一些必要的js和css,以便在_Layout中引用,避免写很多的引入文件。
public class BundleConfig { // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862 public static void RegisterBundles(BundleCollection bundles) { bundles.Add(new ScriptBundle("~/bundles/jquery").Include( "~/Scripts/jquery-{version}.js")); bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( "~/Scripts/jquery.validate*")); // Use the development version of Modernizr to develop with and learn from. Then, when you're // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( "~/Scripts/modernizr-*")); bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( "~/Scripts/bootstrap.js", "~/Scripts/respond.js")); bundles.Add(new StyleBundle("~/Content/css").Include( "~/Content/bootstrap.css", "~/Content/site.css")); } }
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - 我的 ASP.NET 应用程序</title> @Styles.Render("~/Content/css") @Scripts.Render("~/bundles/modernizr") </head> <body> <div class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> @Html.ActionLink("应用程序名称", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" }) </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li>@Html.ActionLink("主页", "Index", "Home")</li> <li>@Html.ActionLink("关于", "About", "Home")</li> <li>@Html.ActionLink("联系方式", "Contact", "Home")</li> </ul> </div> </div> </div> <div class="container body-content"> @RenderBody() <hr /> <footer> <p>© @DateTime.Now.Year - 我的 ASP.NET 应用程序</p> </footer> </div> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/bootstrap") @RenderSection("scripts", required: false) </body> </html>
_Layout文件中通过@Scripts.Render和@Styles.Render去引入。同时可以看到在_Layout布局页中有 @RenderBody() 和 @RenderSection("scripts", required: false)这两个,@RenderBody显示内容页的内容,@RenderSection 留给内容页添加自己需要的内容,其中required参数如果为true或留空,内容页则必须包含该section节点。
那么这个时候可能会想_Layout文件是怎么加载的,其实是在 Views/_ViewStart.cshtml中指定的,因为MVC在渲染视图时会先去Views文件夹下找_ViewStart,在里面指定了Layout。
@{ Layout = "~/Views/Shared/_Layout.cshtml"; }
二、数据传值的几种方式
1、ViewData:ViewData是ViewDataDictionary类型,本质上是一个Dictionary,它的调用方式
ViewData["User"] = new User() { Id = 7, Name = "张三", Account = "zhangshan" };
取值的时候需要进行类型转换
User userViewData = ViewData["User"] as User;
2、ViewBag:ViewBag是dynamic类型的,它可以直接通过 点 来赋值
ViewBag.Something = 23456; ViewBag.Name = "Eleven"; ViewBag.Description = "Teacher";//js ViewBag.User = new User() { Id = 7, Name = "张三", Account = "", };
取值的时候可以直接使用
User userViewBag = ViewBag.User;
3、TempData:TempData是TempDataDictionary类型,和ViewData相似,不同的是它是基于session的,可以跨action访问,而ViewData和ViewBag无法跨action。
public ActionResult Action1{ TempData["User"] = new User() { Id = 7, Name = "张三", Account = "zhangsan", }; return this.RedirectToAction("TempDataPage"); } public ActionResult TempDataPage() { base.ViewBag.User = base.TempData["User"]; return View(); }
三、Razor视图
@字符:@是Razor中的一个重要符号,它被定义为Razor服务器代码块的开始符号。
1. 行内标记:@DateTime.Now.ToString("yyyy-MM-dd")
2. 单行标记:@{ string name = "张三"; string name2 = "李四";}
3. 多行标记:
@{ var age = 25; Response.Write("Age:" + age); }
4. 在遇到如if、for、while等具有"keyword(){}"形式的C#代码结构时,Razor标记可以写成"@keyword(){}"这样的特殊形式。
@if (1 > 2) { <p>1 > 2</p> } else { <p>1 < 2</p> }
5. 服务器代码里嵌入html代码
在Razor标记的代码中如果有成对的html标记,则这个标记及其内容会被当作普通文本输出。
在Razor标记的代码中如果有"@:",则其后的一行代码会被当作普通文本输出。
在Razor标记的代码中如果有<text> </text>标记,则其内容会被当作普通文本输出
四、HtmlHelper/AjaxHelper
@Html.ActionLink:
ActionLink用来生成HTML中的a标签,LinkText是链接显示出的文字,如果ActionLink的参数中给出Controller则链接指向对应的Controller下的Action。如果没有给出Controller则指向当前页面对应的Controller下的Action。如果ActionLink的参数中给出要传递的参数,如id,则在链接的最后写出id值。
@Html.ActionLink("LinkText", "RazorShow") @Html.ActionLink("带控制器", "ActionName", "ControllerName") @Html.ActionLink("带路由信息", "ActionName", new { id = 1, name = 3, age = 4, height = 5 }) <a href="/Html/ActionName/1?name=3&age=4&height=5">带路由信息</a> @Html.ActionLink("链接", "action", new { id = 1, name = 3, age = 4, height = 5 }, new { @class = "classText", style = "width:200px", tt = "xxx" })
@Html.RouteLink:
RouteLink同样是用来生成HTML中的a标签的,但是其参数和ActionLink不同,LinkText依然是链接显示的文字,而链接的其他信息则包含在RouteLink的第二个参数中。这个参数是个Object,它的action属性表示指向的Action而controller属性表示指向的Controller。如果没有controller属性则指向当前Controller。id属性则为要传递的参数。
@Html.RouteLink("LinkText", new { action = "ActionName" }) @Html.RouteLink("LinkText", new { action = "ActionName", controller = "ControllerName" }) @Html.RouteLink("LinkText", new { action = "ActionName", id = 1 })
System.Web.Mvc.Html下还有很多其他的扩展,比如 InputExtensions、FormExtensions
@Html.DropDownList("NameId", list) @Html.RadioButton("NameId", "Value", true) @using (Html.BeginForm("PostData", "Html", FormMethod.Get)) { @Html.TextBox("username") @Html.Password("password") <input type="submit" value="提交" /> } <p>等于webform的ascx</p> <p>Html.RenderPartial 在指定位置添加一个view,返回void 需要放入大括号 </p> @{Html.RenderPartial("PartialPage", "这里是Html.RenderPartial");} <p>Html.Partial 返回的是字符串,放入当前位置</p> @Html.Partial("PartialPage", "这里是Html.Partial") <p>Html.Action 返回的是字符串,放入当前位置,需要经过action的处理</p> @Html.Action("Render", "Second", new { name = "Html.Action" }) <p>Html.RenderAction 在指定位置添加一个view,返回void 需要放入大括号,需要经过action的处理</p> @{Html.RenderAction("Render", "Second", new { name = "Html.RenderAction" });}
@Ajax.BeginForm:异步调用
@Ajax.BeginForm("actionname", new AjaxOptions() { HttpMethod="Post" });
五、分布视图: PartialView
[ChildActionOnly]//不能被单独请求 public ActionResult Render() { ViewBag.Name = "jesen"; return PartialView() //指定分部视图,在_ViewStatrt.cshtml中指定的Layout会无效 }
<p>Html.RenderPartial 在指定位置添加一个view,返回void 需要放入大括号 </p> @{Html.RenderPartial("PartialPage", "这里是Html.RenderPartial");} <p>Html.Partial 返回的是字符串,放入当前位置</p> @Html.Partial("PartialPage", "这里是Html.Partial")
<p>Html.Action 返回的是字符串,放入当前位置,需要经过action的处理</p>
@Html.Action("Render", "Second", new { name = "Html.Action" })