<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      ASP.NET MVC 4 (一)路徑映射

      正如ASP.NET MVC名字所揭示的一樣,是以模型-視圖-控制設計模式構建在ASP.NET基礎之上的WEB應用程序,我們需要創建相應的程序類來協調處理,完成從客戶端請求到結果相應的整個過程:

      VS2012中一個典型的MVC工程結構是這樣的:

      Controllers文件夾下存放控制類,Models文件下是業務數據模型類,Views文件下則是類似于aspx的視圖文件。在傳統ASP.NET form的應用程序中,客戶端的請求最后都映射到磁盤上對應路徑的一個aspx的頁面文件,而MVC程序中所有的網絡請求映射到控制類的某一個方法,我們就從控制類說起,而在講控制類前,必須要講的是URL路由。

      注冊URL路由

      我們在瀏覽器中請求鏈接 http://mysite.com/Home/Index,MVC認為是這樣的URL模式(默認路徑映射):

      {controller}/{action} 

      也就是說上面的請求會被映射到Home控制類的Index方法,MVC命名規則中控制類必須以Controller結尾,所以Home控制類應該是HomeController: 

      public class HomeController : Controller
          {
              public ActionResult Index()
              {
                  return View();
              }
      
          }

       MVC是根據什么將上面的請求映射到控制類的相應方法的呢?答案就是路由表,Global.asax在應用程序啟動時會調用路由配置類來注冊路徑映射:

      public class MvcApplication : System.Web.HttpApplication
          {
              protected void Application_Start()
              {
                  AreaRegistration.RegisterAllAreas();
      
                  WebApiConfig.Register(GlobalConfiguration.Configuration);
                  FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                  RouteConfig.RegisterRoutes(RouteTable.Routes);
                  BundleConfig.RegisterBundles(BundleTable.Bundles);
              }
          }

      路徑映射的配置類則在App_Start目錄下:

      public class RouteConfig
          {
              public static void RegisterRoutes(RouteCollection routes)
              {
                  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
      
                  routes.MapRoute(
                      name: "Default",
                      url: "{controller}/{action}/{id}",
                      defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
                  );
              }
          }

      routes.MapRoute()添加了一個URL路由到路由表中,URL的映射模式是"{controller}/{action}/{id}",controller和action我們已經清楚,id則是請求中額外的參數,比如我們的請求可以是 http://mysite.com/Home/Index/3,對應的action方法可以是:

      public ActionResult Index(int id=1)
      {
        return View();
      }

      在傳遞到Index方法時參數id會被賦值3(保存在RouteData.Values["id"]),MVC足夠智能來解析參數并轉化為需要的類型,MVC稱之為模型綁定(后續具體來看)。上面注冊路由時使用了默認參數:defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },如果我們在請求URL沒有指定某些參數,defaults參數會被用作默認值,比如:

      mydomain.com = mydomain.com/home/index
      mydomain.com/home = mydomain/home/index
      mydomain.com/customer = mydomain/customer/index

      id為可選參數,可以不包括在URL請求中,所以上面注冊的路徑可以映射的URL有:

      mydomain.com
      mydomain.com/home
      mydomain.com/home/list
      mydomain.com/customer/list/4

      除此之外不能映射的請求都會得到404錯誤,比如mydomain.com/customer/list/4/5,這里參數過多不能被映射。

      RouteCollection.MapRoute()等同于:

      Route myRoute = new Route("{controller}/{action}", new MvcRouteHandler()); 
      routes.Add("MyRoute", myRoute); 

      這里直接向Routes表添加一個Route對象。

      其他一些URL映射的例子:

      routes.MapRoute("", "Public/{controller}/{action}",new { controller = "Home", action = "Index" }); //URL可以包含靜態的部分,這里的public
      routes.MapRoute("", "X{controller}/{action}"); //所有以X開頭的控制器路徑,比如mydomain.com/xhome/index映射到home控制器
      routes.MapRoute("ShopSchema", "Shop/{action}",new { controller = "Home" }); //URL可以不包含控制器部分,使用這里的默認Home控制器
      routes.MapRoute("ShopSchema2", "Shop/OldAction",new { controller = "Home", action = "Index" }); //URL可以是全靜態的,這里mydomain.com/shop/oldaction傳遞到home控制器的index方法

      一個比較特殊的例子:

      routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }); 

      這可以映射任意多的URL分段,id后的所有內容都被賦值到cathall參數,比如/Customer/List/All/Delete/Perm,catchall = Delete/Perm。

      需要注意的是路徑表的注冊是有先后順序的,按照注冊路徑的先后順序在搜索到匹配的映射后搜索將停止。

      命名空間優先級

      MVC根據{controller}在應用程序集中搜索同名控制類,如果在不同命名空間下有同名的控制類,MVC會給出多個同名控制類的異常,我們可以在注冊路由的時候指定搜索的命令空間:

      routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional , 
      new[] { "URLsAndRoutes.AdditionalControllers" }); 

      這里表示我們將在"URLsAndRoutes.AdditionalControllers"命名空間搜索控制類,可以添加多個命名空間,比如:

      routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional }, 
      new[] { "URLsAndRoutes.AdditionalControllers", "UrlsAndRoutes.Controllers"}); 

      "URLsAndRoutes.AdditionalControllers", "UrlsAndRoutes.Controllers"兩個命名空間是等同處理沒有優先級的區分,如果這兩個空間里有重名的控制類一樣導致錯誤,這種情況可以分開注冊多條映射:

      routes.MapRoute("AddContollerRoute", "Home/{action}/{id}/{*catchall}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional }, 
      new[] { "URLsAndRoutes.AdditionalControllers" }); 
      routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}", 
      new { controller = "Home", action = "Index", id = UrlParameter.Optional }, 
      new[] { "URLsAndRoutes.Controllers" }); 

      路由限制

      除了在注冊路由映射時可以指定控制器搜索命名空間,還可以使用正則表達式限制路由的應用范圍,比如:

      routes.MapRoute("MyRoute", "{controller}/{action}/{id}/{*catchall}",
      new { controller = "Home", action = "Index", id = UrlParameter.Optional },
      new { controller = "^H.*", action = "^Index$|^About$", httpMethod = new HttpMethodConstraint("GET")},
      new[] { "URLsAndRoutes.Controllers" }); 

      這里限制MyRoute路由僅用于映射所有H開頭的控制類、且action為Index或者About、且HTTP請求方法為GET的客戶端請求。

      如果標準的路由限制不能滿足要求,可以從IRouteConstraint接口擴展自己的路由限制類:

      public class UserAgentConstraint : IRouteConstraint {
      
              private string requiredUserAgent;
      
              public UserAgentConstraint(string agentParam) {
                  requiredUserAgent = agentParam;
              }
      
              public bool Match(HttpContextBase httpContext, Route route, string parameterName,
                                RouteValueDictionary values, RouteDirection routeDirection) {
      
                  return httpContext.Request.UserAgent != null &&httpContext.Request.UserAgent.Contains(requiredUserAgent);
              }
          }

      在注冊路由時這樣使用:

          routes.MapRoute("ChromeRoute", "{*catchall}",
              new { controller = "Home", action = "Index" },
              new { customConstraint = new UserAgentConstraint("Chrome")},
              new[] { "UrlsAndRoutes.AdditionalControllers" });

      這表示我們限制路由僅為瀏覽器Agent為Chrome的請求時使用。

      路由到磁盤文件

      除了控制器方法,我們也需要返回一些靜態內容比如HTML、圖片、腳本到客戶端,默認情況下路由系統優先檢查是否有和請求路徑一致的磁盤文件存在,如果有則不再從路由表中匹配路徑。我們可以通過配置顛倒這個順序:

      public static void RegisterRoutes(RouteCollection routes) { 
      routes.RouteExistingFiles = true; 
      ... ....

      還需要修改web配置文件:

      <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition=""/> 

      這里設置preCondition為空。如果我們再請求一些靜態內容比如~/Content/StaticContent.html時會優先從路徑表中匹配。

      而如果我們又需要忽略某些路徑的路由匹配,可以:

      ... 
      public static void RegisterRoutes(RouteCollection routes) { 
      routes.RouteExistingFiles = true; 
      routes.IgnoreRoute("Content/{filename}.html"); 
      ...

      它會在RouteCollection中添加一個route handler為StopRoutingHandler的路由對象,在匹配到content路徑下的后綴為html的文件時停止繼續搜索路徑表,轉而匹配磁盤文件。

      生成對外路徑

      路徑表注冊不僅影響到來自于客戶端的URL映射,也影響到我們在視圖中使用HTML幫助函數生成對外路徑,比如我們注冊了這樣的映射

      public class RouteConfig { 
      public static void RegisterRoutes(RouteCollection routes) { 
      routes.MapRoute("MyRoute", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }); 
      } 
      ...

      在視圖中調用Html.ActionLink生成一個對外路徑:

      <div> 
      @Html.ActionLink("This is an outgoing URL", "CustomVariable") 
      </div> 

      根據我們當前的請求鏈接,http://localhost:5081/home,生成的outgoing鏈接為: 

      <a href="/Home/CustomVariable">This is an outgoing URL</a> 

      而如果我們調整路徑表為:

      ... 
      public static void RegisterRoutes(RouteCollection routes) { 
      routes.MapRoute("NewRoute", "App/Do{action}", new { controller = "Home" }); 
      routes.MapRoute("MyRoute", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }); 
      } 
      ... 

      “@Html.ActionLink("This is an outgoing URL", "CustomVariable") ”得到的結果是:

      <a href="/App/DoCustomVariable">This is an outgoing URL</a>

      它將使用在路徑表中找到的第一條匹配的記錄來生成相應的鏈接路徑。

      Html.ActionLink()有多個重載,可以多中方式生成URL鏈接:

      @Html.ActionLink("This targets another controller", "Index", "Admin") //生成到Admin控制器Index方法的鏈接
      @Html.ActionLink("This is an outgoing URL", 
      "CustomVariable", new { id = "Hello" }) //生成額外參數的鏈接,比如上面的路徑配置下結果為“href="/App/DoCustomVariable?id=Hello"”;如果路徑映射為 "{controller}/{action}/{id}",結果為href="/Home/CustomVariable/Hello"
      @Html.ActionLink("This is an outgoing URL", "Index", "Home", null, new {id = "myAnchorID", @class = "myCSSClass"}) //設定生成A標簽的屬性,結果類似“<a class="myCSSClass"href="/" id="myAnchorID">This is an outgoing URL</a> ”

      參數最多的調用方式是:

      @Html.ActionLink("This is an outgoing URL", "Index", "Home", 
      "https", "myserver.mydomain.com", " myFragmentName", 
      new { id = "MyId"}, 
      new { id = "myAnchorID", @class = "myCSSClass"})

      得到的結果是:

      <a class="myCSSClass"  id="myAnchorID">This is an outgoing URL</a> 

       Html.ActionLink方法生成的結果中帶有HTML的<a>標簽,而如果只是需要URL,可以使用Html.Action(),比如:

      @Url.Action("Index", "Home", new { id = "MyId" }) //結果為單純的/home/index/myid

      如果需要在生成URL指定所用的路徑記錄,可以:

      @Html.RouteLink("Click me", "MyOtherRoute","Index", "Customer") //指定使用路徑注冊表中的MyOtherRoute記錄

      上面講的都是在Razor引擎視圖中生成對外URL,如果是在控制器類中我們可以:

      string myActionUrl = Url.Action("Index", new { id = "MyID" }); 
      string myRouteUrl = Url.RouteUrl(new { controller = "Home", action = "Index" }); 

      更多的情況是在控制類方法中需要轉到其他的Action,我們可以:

      ... 
      public RedirectToRouteResultMyActionMethod() { 
        return RedirectToAction("Index");
      } 
      ... 
      public RedirectToRouteResult MyActionMethod() { 
        return RedirectToRoute(new { controller = "Home", action = "Index", id = "MyID" }); 
      } 
      ...

      創建自定義ROUTE類

      除了使用MVC自帶的Route類,我們可以從RouteBase擴展自己的Route類來實現自定義的路徑映射:

      public class LegacyRoute : RouteBase
          {
              private string[] urls;
      
              public LegacyRoute(params string[] targetUrls)
              {
                  urls = targetUrls;
              }
      
              public override RouteData GetRouteData(HttpContextBase httpContext)
              {
                  RouteData result = null;
      
                  string requestedURL = httpContext.Request.AppRelativeCurrentExecutionFilePath;
                  if (urls.Contains(requestedURL, StringComparer.OrdinalIgnoreCase))
                  {
                      result = new RouteData(this, new MvcRouteHandler());
                      result.Values.Add("controller", "Legacy");
                      result.Values.Add("action", "GetLegacyURL");
                      result.Values.Add("legacyURL", requestedURL);
                  }
                  return result;
              }
      
              public override VirtualPathData GetVirtualPath(RequestContext requestContext,
                  RouteValueDictionary values)
              {
      
                  VirtualPathData result = null;
      
                  if (values.ContainsKey("legacyURL") &&
                      urls.Contains((string)values["legacyURL"], StringComparer.OrdinalIgnoreCase))
                  {
                      result = new VirtualPathData(this,
                          new UrlHelper(requestContext)
                              .Content((string)values["legacyURL"]).Substring(1));
                  }
                  return result;
              }
          }

      GetRouteData()函數用于處理URL請求映射,我們可以這樣注冊路徑映射:

      routes.Add(new LegacyRoute( 
      "~/articles/Windows_3.1_Overview.html", 
      "~/old/.NET_1.0_Class_Library")); 

      上面的例子中如果我們請求"~/articles/Windows_3.1_Overview.html"將被映射到Legacy控制器的GetLegacyURL方法。

      GetVirtualPath()方法則是用于生成對外鏈接,在視圖中使用:

      @Html.ActionLink("Click me", "GetLegacyURL", new { legacyURL = "~/articles/Windows_3.1_Overview.html" }) 

      生成對外鏈接時得到的結果是:

      <a href="/articles/Windows_3.1_Overview.html">Click me</a>

      創建自定義ROUTE Handler

      除了可以創建自定義的Route類,還可以創建自定義的Route handler類:

      public class CustomRouteHandler : IRouteHandler {
              public IHttpHandler GetHttpHandler(RequestContext requestContext) {
                  return new CustomHttpHandler();
              }
          }
      
          public class CustomHttpHandler : IHttpHandler {
              public bool IsReusable {
                  get { return false; }
              }
      
              public void ProcessRequest(HttpContext context) {
                  context.Response.Write("Hello");
              }
          }

      注冊路徑時使用自定義的Route handler:

      routes.Add(new Route("SayHello", new CustomRouteHandler()));

      其效果就是針對鏈接 /SayHello的訪問得到的結果就是“Hello”。

      使用Area

      大型的Web應用可能分為不同的子系統(比如銷售、采購、管理等)以方便管理,可以在MVC中創建不同的Area來劃分這些子系統,在VS中右鍵點擊Solution exploer->Add->Area可以添加我們想要的區域,在Solution exploer會生成Areas/<區域名稱>的文件夾,其下包含Models、Views、Controllers三個目錄,同時生成一個AreaRegistration的子類,比如我們創建一個名為Admin的區域,會自動生成名為AdminAreaRegistration的類:

      namespace UrlsAndRoutes.Areas.Admin {
          public class AdminAreaRegistration : AreaRegistration {
              public override string AreaName {
                  get {
                      return "Admin";
                  }
              }
      
              public override void RegisterArea(AreaRegistrationContext context) {
                  context.MapRoute(
                      "Admin_default",
                      "Admin/{controller}/{action}/{id}",
                      new { action = "Index", id = UrlParameter.Optional }
                  );
              }
          }
      }

      它的主要作用是注冊一個到Admin/{controller}/{action}/{id}路徑映射,在global.asax中會通過AreaRegistration.RegisterAllAreas()來調用到這里的RegisterArea()來注冊區域自己的路徑映射。

      在Area下創建Controller、視圖同整個工程下創建是相同的,需要注意的是可能遇到控制器重名的問題,具體解決參見命名空間優先級一節。

      如果在視圖中我們需要生成到特定Area的鏈接,可以在參數中指定Area:

      @Html.ActionLink("Click me to go to another area", "Index", new { area = "Support" }) 

      如果需要得到頂級控制器的鏈接area=""留空即可。

       

      以上為對《Apress Pro ASP.NET MVC 4》第四版相關內容的總結,不詳之處參見原版 http://www.apress.com/9781430242369。  

      posted @ 2016-09-02 22:05  閆寶平  閱讀(1486)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲国产精品人人做人人爱| 精品无码久久久久久尤物| 蜜桃av无码免费看永久| 国产一区精品综亚洲av| 国产福利酱国产一区二区| 99精品国产一区二区三区2021 | 亚洲综合日韩av在线| а∨天堂一区中文字幕| 麻豆成人传媒一区二区| 国产欧美一区二区精品性色| 亚洲成在人线AⅤ中文字幕| 高清性欧美暴力猛交| 3d动漫精品一区二区三区| 自拍偷拍视频一区二区三区| 免费国产一区二区不卡| 国产色无码精品视频免费| 四虎网址| 久久久欧美国产精品人妻噜噜| 人人妻碰人人免费| 久久国产精品老人性| 精品人妻伦九区久久69| 龙游县| 国产精品中文字幕日韩| 四虎影视库国产精品一区| 另类国产精品一区二区| 人妻中文字幕精品一页| 久久久久无码中| 夜夜春久久天堂亚洲精品| 亚洲av永久无码精品水牛影视 | 在线中文字幕国产精品| 成人福利国产午夜AV免费不卡在线 | 艳妇臀荡乳欲伦69调教视频| 激情五月天自拍偷拍视频| 亚洲一区久久蜜臀av| 另类 亚洲 图片 激情 欧美| 中文字幕国产精品一二区| 思思久99久女女精品| 综合区一区二区三区狠狠| 老熟妇仑乱换频一区二区| 一区二区三区不卡国产| 日韩av中文字幕有码|