咱們先建立一個ASP.NET Web程序css
模板選擇MVC,由於不想使用默認的身份認證咱們點擊更改身份認證並選擇不進行身份認證。html
建立的項目結構以下:web
查看項目的web.config文,首先是appSettingsbootstrap
<appSettings>app
<add key="webpages:Version" value="3.0.0.0" />框架
<add key="webpages:Enabled" value="false" />ide
<add key="ClientValidationEnabled" value="true" />函數
<add key="UnobtrusiveJavaScriptEnabled" value="true" />ui
</appSettings>this
先是設置webpages框架的版本webpages:Version,而後是設置webpages:Enabled防止webpages頁面(cshtml )的直接執行。
ClientValidationEnabled和UnobtrusiveJavaScriptEnabled主要用於各htmlhelper方法,控制生成的客戶端html代碼,其中ClientValidationEnabled是指是否開啓客戶端驗證,UnobtrusiveJavaScriptEnabled是指是否開啓非侵入式JavaScript驗證(經過給html元素添加元屬性實現驗證),這裏不作過多深刻。
<system.web>
<compilation debug="true" targetFramework="4.6" />
<httpRuntime targetFramework="4.6" />
</system.web>
System.web的設置目前很簡單,只是設置了debug和.net版本。
再下面是封裝每一個程序集的綁定策略和程序集位置,每一個程序集使一個dependentAssembly 元素。最後是指定可用語言提供程序的編譯器配置設置。
此外還有默認生成的兩個配置文件分別是用於Debug和Release模式的,根據配置的不一樣將對應的配置文件添加到最終生成的web.config中。
再來查看默認生成的Global.asax文件,咱們知道在第一次請求的時候該文件就已經被編譯並會調用其中定義的Application_Start方法。
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
首先是註冊全部的區域,其實如今AreaRegistration類中(在System.Web.Mvc下實現)。
public static void RegisterAllAreas() { RegisterAllAreas(null); } public static void RegisterAllAreas(object state) { RegisterAllAreas(RouteTable.Routes, new BuildManagerWrapper(), state); } internal static void RegisterAllAreas(RouteCollection routes, IBuildManager buildManager, object state) { List<Type> areaRegistrationTypes = TypeCacheUtil.GetFilteredTypesFromAssemblies(TypeCacheName, IsAreaRegistrationType, buildManager); foreach (Type areaRegistrationType in areaRegistrationTypes) { AreaRegistration registration = (AreaRegistration)Activator.CreateInstance(areaRegistrationType); registration.CreateContextAndRegister(routes, state); } }
其中TypeCacheUtil.GetFilteredTypesFromAssemblies會掃描全部相關程序集(BuildManager.GetReferencedAssemblies)獲取實現了AreaRegistration的類(並且必須有可訪問的無參的構造函數)。而後建立實例並調用CreateContextAndRegister註冊區域。
internal void CreateContextAndRegister(RouteCollection routes, object state) { AreaRegistrationContext context = new AreaRegistrationContext(AreaName, routes, state); string thisNamespace = GetType().Namespace; if (thisNamespace != null) { context.Namespaces.Add(thisNamespace + ".*"); } RegisterArea(context); }
其中具體的註冊方法RegisterArea是一個虛方法,咱們建立一個區域看看它是如何實現的,在MVC程序中經過右鍵建立一個名爲Teacher的區域,自動生成的AreaRegistration代碼以下:
public class TeacherAreaRegistration : AreaRegistration { public override string AreaName { get { return "Teacher"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Teacher_default", "Teacher/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional } ); } }
能夠看到最終是經過AreaRegistrationContext的MapRoute向RouteTable註冊了路由。
public Route MapRoute(string name, string url, object defaults, object constraints, string[] namespaces) { if (namespaces == null && Namespaces != null) { namespaces = Namespaces.ToArray(); } Route route = Routes.MapRoute(name, url, defaults, constraints, namespaces); route.DataTokens[RouteDataTokenKeys.Area] = AreaName; bool useNamespaceFallback = (namespaces == null || namespaces.Length == 0); route.DataTokens[RouteDataTokenKeys.UseNamespaceFallback] = useNamespaceFallback; return route; }
能夠知道AreaName被註冊到了route.DataTokens[RouteDataTokenKeys.Area]中。
接下來看Global.asax的下面三行代碼:
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
這是咱們比較熟悉的註冊全局過濾器、註冊路由和註冊綁定(主要是css和js資源)了。其實際工做有一下三個類完成。對於過濾器和路由的機制留到之後再詳細分析,這裏簡單介紹一下資源綁定。
查看具體的代碼
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"));
咱們能夠看到兩種綁定ScriptBundle(js腳本)和StyleBundle(css),值得注意的是StyleBundle方法的參數virtualPath須要根據綁定的css來設置(設置成css文件同目錄,避免css中的一些相對路徑失效),若是js腳本中有引用其餘腳本也是同樣。頁面使用時直接經過Scripts或Styles的靜態方法Render(paths)在頁面中引用資源。