<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


        ?ASP.NET Core MVC 路由是建立在ASP.NET Core
      路由的,一項強大的URL映射組件,它可以構(gòu)建具有理解和搜索網(wǎng)址的應(yīng)用程序。這使得我們可以自定義應(yīng)用程序的URL命名形式,使得它在搜索引擎優(yōu)化(SEO)和鏈接生成中運行良好,而不用關(guān)心Web服務(wù)器上的文件是怎么組織的。我們可以方便的使用路由模板語法定義路由,路由模板語法支持路由值約束,默認(rèn)值和可選值。


        基于約束的路由允許全局定義應(yīng)用支持的URL格式,以及這些格式是怎樣各自在給定的控制器中映射到指定的操作方法(Action)。當(dāng)接受到一個請求時,路由引擎解析URL并將其匹配至一個定義URL格式,然后調(diào)用相關(guān)的控制器操作方法。 
      routes.MapRoute( name: "default", template: "
      {controller=Home}/{action=Index}/{id?}");
        特性路由(Attribute Routing)
      允許以在控制器和方法使用添加特性的方式指定路由信息來定義應(yīng)用程序的路由。這意味著路由定義緊鄰它們所關(guān)聯(lián)的控制器和方法。

        ASP.NET Core MVC
      使用路由中間件來匹配傳入請求的URL,并將它們映射到操作方法。路由在啟動代碼或?qū)傩灾卸x,它描述了網(wǎng)址路徑應(yīng)如何與操作方法匹配,還用于響應(yīng)中生成鏈接并發(fā)送。

      ?

      1.設(shè)置路由中間件

        創(chuàng)建一個ASP.NET Core Web應(yīng)用程序,在Startup類的Configure方法中有:
      app.UseMvc(routes => { routes.MapRoute( name: "default", template: "
      {controller=Home}/{action=Index}/{id?}"); });
        在對UseMvc的調(diào)用過程中,MapRoute用于創(chuàng)建單個路由,即默認(rèn)路由。大多數(shù)MVC應(yīng)用程序都使用與默認(rèn)路由模板類似的路由。

        路由模板{controller=Home}/{action=Index}/{id?} 可以匹配類似 Blog/Details/5
      的URL路徑,并且提取路由值?{controller=Blog,action=Details,id=5}。MVC將嘗試查找名為BlogController的控制器,并運行操作方法。

          {controller=Home}將Home定義為默認(rèn)控制器

          {action=Index}將Index定義為默認(rèn)操作

          {id?}將id定義為可選

          默認(rèn)路徑參數(shù)和可選路徑參數(shù)可以不出現(xiàn)在需要匹配的URL路徑中。

        使用{controller=Home}/{action=Index}/{id?}模板,可以對以下URL路徑都執(zhí)行HomeController.Index:

          /Home/Index/7

          /Home/Index

          /Home

          /

      ?

        有個簡單方法 app.UseMvcWithDefaultRoute() 可以替換掉上面的方法。

        UseMvc 和?UseMvcWithDefaultRoute
      都是將RouteMiddleware的實例添加到中間件管道。MVC不直接與中間件交互,而是使用路由來處理請求。MVC通過MvcRouteHandler的實例鏈接到路由。下面的代碼與UseMvc類似: 
      var route = new RouteBuilder(app); //添加連接到MVC,通過調(diào)用MapRoute來回調(diào)
      route.DefaultHandler =new MvcRouteHandler(...); //執(zhí)行回調(diào)以注冊路由 route.MapRoute("
      default", "{controller=Home}/{action=Index}/{id?}"); //創(chuàng)建路由集合并添加至中間件
      app.UseRouter(route.Build());
        UseMvc 不直接定義任何路由,它為屬性路由的路由集合添加一個占位符。重載UseMvc 使得我們可以添加自己的路由,并且還支持屬性路由。UseMvc
      及其所有變體為屬性路由添加了占位符,這使得屬性路由始終可用。UseMvcWithDefaultRoute定義默認(rèn)路由并且支持屬性路由。

      ?

      2.常規(guī)路由

         routes.MapRoute(name: "default",template:
      "{controller=Home}/{action=Index}/{id?}");??這是一個常規(guī)路由,因為它建立了一個約定的URL路徑:

          第一路徑段映射到控制器名稱

          第二路徑映射到操作名稱

          第三區(qū)段是可選id,用于映射到模型實體

      ?

        使用default路由,URL 路徑 /Blog/Index 將映射到BlogController.Index
      操作。該映射是基于控制器和操作名稱,而不是基于命名空間,源文件位置等。

        使用常規(guī)路由的默認(rèn)路由可以快速構(gòu)建應(yīng)用程序,而無需定義每一個操作的路由。對于CRUD 操作風(fēng)格的應(yīng)用程序,整個控制器的URL具有一致性。

      ?

      3.多路由

        可以在UseMvc 里面通過添加MapRoute 來添加多個路由。這樣可以定義多個約定,或添加專用于特定操作的常規(guī)路由: 
      app.UseMvc(routes => { routes.MapRoute("blog", "blog/{*article}", defaults: new
      { Controller ="Blog", Action = "Index" }); routes.MapRoute( name: "default",
      template:"{controller=Home}/{action=Index}/{id?}"); });
        這里的blog 路由是專用常規(guī)路由,這意味著它不采用常規(guī)路由系統(tǒng),而是專用于一個特定地的動作。這個路由始終映射到BlogController.Index。

        路由集合中的路由是有序的,并且會按照它們被添加的順序進(jìn)行處理。

        

        1.回退


        作為請求處理的一部分,MVC將驗證路由值是否可以用來查找應(yīng)用程序中的控制器和操作。如果路由值不匹配操作,那么該路由被認(rèn)為是不匹配的,將嘗試下一個路由。這一過程稱為回退,因為常規(guī)路由有重疊的情況。

        

        2.行動歧義


        當(dāng)兩個一致的操作通過路由時,MVC必須消除歧義,選擇最佳操作,否則會拋出異常。例如:
      public class BlogController : Controller { public ActionResult Edit(int id) {
      return View(); } [HttpPost] public ActionResult Edit(int id, IFormCollection
      collection) {try { // TODO: Add update logic here return
      RedirectToAction(nameof(Index)); }catch { return View(); } } }
        URL /Blog/Edit/7
      可以匹配這兩個操作,這是MVC控制器的典型模式,其中Edit(int)用于顯示編輯的表單,Edit(int,IFormCollection)用于
      處理已提交的表單。為了達(dá)到這個目的,MVC需要在HTTP
      POST時選擇Edit(int,IFormCollection),在其他HTTP動詞時選擇Edit(int)。

        HttpPostAttribute 是IActionConstraint
      的一個實現(xiàn),它只允許在HTTP動詞為POST時選擇動作。IActionConstraint的存在使得Edit(int,IFormCollection)比Edit(int)更好匹配。

        如果有多個路由匹配,并且MVC無法找到一個最佳路由,則會拋出AmbiguousActionException異常。

      ?

        3.路由名稱

        
      上面的例子中"blog"和"default"字符串是路由名稱,路由名稱為路由提供了一個邏輯名稱,以便命名的路由可用于生成URL。在應(yīng)用程序范圍內(nèi)路由必須名稱必須是唯一的。

        路由名稱對URL匹配或請求的處理沒有影響,僅用于URL生成。

      ?

      4.路由特性

        特性路由使用一組特性直接將操作映射到路由模板。下面在Configure中調(diào)用 app.UseMvc(); 沒有傳遞路由。
      public class HomeController : Controller { [Route("")] [Route("Home")] [Route("
      Home/Index")] public IActionResult Index() { return View(); } [Route("Home/About
      ")] public IActionResult About() { ViewData["Message"] = "Your application
      description page."; return View(); } }
        HomeController.Index操作將會對 /,/Home 或者/Home/Index 任一URL訪問執(zhí)行。

        特性路由需要有更多的輸入來指定一個路由,而常規(guī)路由處理路由時更加簡潔。然而,特性路由允許精準(zhǔn)控制每個操作的路由模板。

        上面的模板中沒有定義針對 action,area
      ,controller的路由參數(shù)。實際上,這些參數(shù)不允許出現(xiàn)在特性路由中,因為路由模板已經(jīng)關(guān)聯(lián)了一個操作,解析URL中的操作名是沒有意義的。

        特性路由也可以使用HTTP[Verb]特性,如HTTPPost:
      [HttpGet("/Blog")] public ActionResult Index() { return View(); }
        由于特性路由適用于特定操作,因此很容易使參數(shù)作為模板定義中必須的一部分。下面的例子,id是URL中必須的一部分:
      [HttpGet("Blog/Edit/{id}")] public ActionResult Edit(int id) { return View(); }
        常規(guī)的默認(rèn)路由定義id參數(shù)作為可選項({id?}),而特性路由的是必須參數(shù),這種可以精準(zhǔn)指定,比如包/Blog/Get 和 /Blog/Get/{id}
      分配到不同的操作。

      ?

      5.組合路由

        為了減少特性路由的重復(fù)部分,控制器上的路由特性會和各個操作上的路由特性進(jìn)行結(jié)合。任何定義在控制器上的路由模板都會作為操作路由模板的前綴。
      [Route("blog")] public class BlogController : Controller { [HttpGet] public
      ActionResult GetAll() {return View(); } [HttpGet("{id}")] public ActionResult
      GetById(int id) { return View(); } }
        /blog 匹配GetAll方法, /blog/1 匹配 GetById方法。

        注意,如果操作上路由模板以 / 開頭時不會結(jié)合控制器上的路由模板。

      ?

      6.特性路由的順序


        常規(guī)路由會根據(jù)定義順序來執(zhí)行,與之相比,特性路由會構(gòu)建一個樹形結(jié)構(gòu),同時匹配所有路由。這種看起來像路由條目被放置在一個理想的順序中,最具體的路由會在一般的路由之前執(zhí)行。比如,路由blog/Edit/4
      比 blog/{*article} 更加具體。

        特性路由使用所有框架提供的路由特有的Order屬性來配置順序,并根據(jù)Order屬性升序處理路由。默認(rèn)是0,設(shè)置為-1時會在沒有設(shè)置的路由之前執(zhí)行。

      ?

      7.路由模板中的標(biāo)記替換( [controller] , [action] , [area])

        為了方便,特性路由支持標(biāo)記替換,即通過在在方括號中封閉一個標(biāo)記([,
      ])來替換對應(yīng)的名稱。標(biāo)記[action],[area],[controller]會被替換成操作所對應(yīng)的操作名,區(qū)域名,控制器名。
      [Route("[controller]/[action]")] public class BlogController : Controller {
      [HttpGet]//匹配Blog/GetAll public ActionResult GetAll() { return View(); } }
        標(biāo)記替換發(fā)生在構(gòu)建特性路由的最后一步。與上面結(jié)果相同的寫法:
      public class BlogController : Controller { [HttpGet("[controller]/[action]")]//
      匹配Blog/GetAll public ActionResult GetAll() { return View(); } }
        特性路由也可以與繼承相結(jié)合,即繼承父類的路由標(biāo)記。

        特性路由支持單個操作定義路由。如果用IActionConstarint實現(xiàn)的多個路由特性定義在一個操作上時,每個操作約束與特性定義的路由相結(jié)合:
      [Route("Store")] [Route("[controller]")] public class BlogController :
      Controller { [HttpGet("GetAll")]//匹配 Get Blog/GetAll和 Store/GetAll [HttpPost("
      Set")]//匹配 Post Blog/Set和 Store/Set public ActionResult GetAll() { return
      View(); } }
        雖然使用多個路由到一個操作看起來很強大,但最好還是保持URL的空間簡單和定義明確。使用多個路由到操作上僅僅在特殊需要的時候,比如支持多個客戶端。

      ?

      8.使用IRouteTemplateProvider自定義路由特性

        所有框架提供的路由特性([Route(...) ] ,[HttpGet(...)]等)都實現(xiàn)了 IRouteTemplateProvider
      接口。當(dāng)程序啟動時,MVC查找控制器類和操作方法上都實現(xiàn)?IRouteTemplateProvider 接口的特性來構(gòu)建儲時路由集合。

        可以通過實現(xiàn)?IRouteTemplateProvider 來定義自己的路由特性。每個?IRouteTemplateProvider
      都允許定義使用自定義路由模板,順序以及名稱的單一路由:
      public class MyApiControllerAttribute:Attribute, IRouteTemplateProvider {
      public string Template => "api/[controller]"; public int? Order { get; set; }
      public string Name { get; set; } }
        當(dāng) [MyApiController] 特性被應(yīng)用時,會自動設(shè)置Template 為?api/[controller] 。

      ?

      9.使用應(yīng)用程序模型來自定義特性路由

        應(yīng)用程序模型時啟動時創(chuàng)建的對象模型,其中包含MVC用于路由和執(zhí)行操作的所有元數(shù)據(jù)。應(yīng)用程序模型包括從路由特性收集的所有數(shù)據(jù)(通過
      IRouteTemplateProvider)。我們可以編寫約定以在啟動時修改應(yīng)用程序模型為自定義路由行為。
      public class NamespaceRoutingConvention:IControllerModelConvention { private
      readonly string _baseNamespace; public NamespaceRoutingConvention(string
      baseNamespace) { _baseNamespace= baseNamespace; } public void
      Apply(ControllerModel controller) {var hasRouteAttributes =
      controller.Selectors.Any(selector => selector.AttributeRouteModel != null); if
      (hasRouteAttributes) {//此控制器自定義了一些路由,因此將其視為覆蓋 return; } // 使用命名空間和控制器來推斷控制器的路由
      // // Example: // // controller.ControllerTypeInfo ->
      "My.Application.Admin.UsersController"// baseNamespace -> "My.Application" // //
      template => "Admin/[controller]"// // 這使得你的路由大致與你的項目結(jié)構(gòu)一致 // var namespc =
      controller.ControllerType.Namespace;var template = new StringBuilder();
      template.Append(namespc,_baseNamespace.Length+1,namespc.Length-
      _baseNamespace.Length-1); template.Replace('.','/'); template.Append("
      /[controller]"); foreach (var selector in controller.Selectors) {
      selector.AttributeRouteModel= new AttributeRouteModel() { Template =
      template.ToString() }; } } }
        這部分怎么使用,個人還是不是很清楚,這里只是記錄了官方文檔,有哪位知道可以告訴以下小弟。

      ?

      10.URL生成

        MVC應(yīng)用程序可以使用路由URL的生成特性來生成URL鏈接到操作。生成URL可以消除硬編碼URL,使代碼更加健壯和易維護(hù)。IUrlHelper
      接口是MVC與生成URL路由之間基礎(chǔ)設(shè)施的基本塊??梢酝ㄟ^控制器,視圖以及視圖組件中的URL屬性找到一個可用的IUrlHelper實例:
      public class HomeController : Controller { public IActionResult Index() { //
      生成/Home/Contact var url = Url.Action("Contact"); return View(); } public
      IActionResult Contact() { ViewData["Message"] = "Your application description
      page."; return View(); } }
        這個URL路徑是由路由值與當(dāng)前請求相結(jié)合而成的路由創(chuàng)建,并將值傳遞給Url.Action,替換路由模板中對應(yīng)的值。


        上面Url.Action(的例子是常規(guī)路由,但是URL的生成工作與特性路由類似,盡管概念不同。在常規(guī)路由中,路由值被用來擴展模板,并且關(guān)于controller和action的路由值通常出現(xiàn)在那個模板,因為路由匹配的URL堅持了一個約定。在特性路由中,關(guān)于controller和action的路由值不允許出現(xiàn)在模板中--它們用來查找應(yīng)該使用哪個模板,例如:
      //修改Configure public void Configure(IApplicationBuilder app,
      IHostingEnvironment env) { app.UseMvc(); }public class HomeController :
      Controller { [HttpGet("/")] public IActionResult Index() { //生成/Home/To/About
      var url = Url.Action("About"); return View(); } [HttpGet("Home/To/About")]
      public IActionResult About() { ViewData["Message"] = "Your application
      description page."; return View(); } }
        MVC構(gòu)建了一個所有特性路由操作的查找表,并且會匹配controller和action值來選擇路由模板用于生成URL。

      ?

      11.通過操作名生成URL

      ? ? ?Url.Action(this IUrlHelper helper, string action)
      以及所有相關(guān)的重載都是基于指定控制器名稱和操作名來指定要鏈接的內(nèi)容。

        當(dāng)使用Url.Action時,controller 和 action 的當(dāng)前路由值是指定的 -- controller 和 action
      的值同時是環(huán)境值和值的一部分。Url.Action 方法總是使用 controller 和 action 的當(dāng)前值,并且生成路由到當(dāng)前操作的URL路徑。

        路由嘗試使用環(huán)境值中的值來填充信息,同時我們也可以指定路由參數(shù):
      public class HomeController : Controller { public IActionResult Index() { //
      生成/Blog/Edit/1 var url = Url.Action("Edit", "Blog",new { id=1}); //
      生成/Blog/Edit/1?color=red var url1 = Url.Action("Edit", "Blog", new { id = 1
      ,color="red"}); return View(); } }
        如果像創(chuàng)建一個絕對URL,可以使用一個接受protocol的重載: Url.Action("Edit", "Blog",new {
      id=1},protocol:Request.Scheme);

        

      12.通過路由名生成URL

        IUrlHelper也提供了 Url.RouteUrl 的系列方法,最常見的是指定一個路由名來使用具體的路由生成URL,通常沒有指定控制器名或操作名:
      public class HomeController : Controller { public IActionResult Index() { //
      生成customer/to/url var url = Url.RouteUrl("AboutRoute"); return View(); }
      [HttpGet("customer/to/url",Name = "AboutRoute")] public IActionResult About() {
      ViewData["Message"] = "Your application description page."; return View(); } }
        在HTML 中生成的URLHtmlHelper,提供了 HtmlHelper 方法 Html.BeginForm 和 Html.ActionLink
      來分別生成<form>和<a>元素。這些方法使用Url.Action方法來生成一個URL,并且它們接受類似的參數(shù)。Url.RouteLink
      ,它們有類似的功能。TagHelper通過form和<a> TagHelper生成URL。這些都使用了IUrlHelper
      作為它們的實現(xiàn)。在內(nèi)部視圖中,IUrlHelper 通過Url 屬性生成任何不包含上述的特定URL。

      ?

      13.在操作結(jié)果中生成URL

        在控制器中常見的一個用法是生成一個URL作為操作結(jié)果的一部分。Controller和ControllerBase
      基類為引用其他操作的操作結(jié)果提供了簡單方法。一個典型的方法:
      public class HomeController : Controller { public IActionResult Index() { //
      生成customer/to/url var url = Url.RouteUrl("AboutRoute"); return Redirect(url); //
      或者//return RedirectToAction("Contact"); } [HttpGet("customer/to/url",Name = "
      AboutRoute")] public IActionResult About() { ViewData["Message"] = "Your
      application description page."; return View(); } public IActionResult Contact()
      { ViewData["Message"] = "Your contact page."; return View(); } }
        RedirectToAction方法有多個重載可以使用。

      ?

      14.專用常規(guī)路由的特殊情況

        有一種特殊的路由被稱為專用常規(guī)路由,下面被命名為blog的路由就是:
      app.UseMvc(routes => { routes.MapRoute("blog", "blog/{*article}", defaults: new
      { Controller ="Blog", Action = "Index" }); routes.MapRoute( name: "default",
      template:"{controller=Home}/{action=Index}/{id?}"); });
        Url.Action("Index", "Home") 會使用默認(rèn)路由生成URL。


        專用常規(guī)路由是依靠默認(rèn)路由的一個特殊行為,沒有相應(yīng)的路由參數(shù),以防止路由生成URL“太貪婪”。當(dāng)路由執(zhí)行URL生成時,提供的值必須與默認(rèn)值匹配:否則使用blog的URL生成失敗,因為值
      {controller=Home,action=Index}不匹配{controller=Blog,action=Index}。然后路由回退嘗試default,并成功。

      ?

      15.區(qū)域

      ?  Areas
      是一種MVC功能,用來將相關(guān)功能組織為一個組,作為單獨的路由命名空間(用于控制器操作)和文件夾結(jié)構(gòu)(用于視圖)。使用區(qū)域允許應(yīng)用程序擁有多個相同名稱的控制器——只要它們具有不同的區(qū)域。使用區(qū)域通過向控制器和操作添加另一個路由參數(shù),區(qū)域可創(chuàng)建用于路由目的的層次結(jié)構(gòu)。

        使用默認(rèn)常規(guī)路由配置MVC,命名一個OMS區(qū)域的路由:
      app.UseMvc(routes => { routes.MapAreaRoute("oms", "OMS", "
      OManage/{controller}/{action}/{id?}", defaults: new { Controller = "Order",
      Action ="Index" }); routes.MapRoute( name: "default", template: "
      {controller=Home}/{action=Index}/{id?}"); }); namespace
      Blog.Areas.OMS.Controllers { [Area("OMS")] public class OrderController :
      Controller {// GET: Order public ActionResult Index() { return View(); } }
        當(dāng)URL為 /OManage/Order/Edit 時,會匹配路由值 {area = OMS,controller = Order , action =
      Edit}。area路由值是通過area默認(rèn)值產(chǎn)生的。使用MapRoute方法也可以實現(xiàn):
      routes.MapRoute("oms", "OManage/{controller}/{action}/{id?}", defaults:new
      {area="OMS" },constraints:new { area = "OMS" });
        MapAreaRoute創(chuàng)建一個路由,同時使用默認(rèn)路由和area 約束,約束使用提供的區(qū)域名 OMS。默認(rèn)值保證路由總是處理 {area =
      OMS},約束要求值{area = OMS} 來進(jìn)行URL生成。

        常規(guī)路由是順序依賴。一般區(qū)域路由放置在前面,因為區(qū)域路由更具體。

        AreaAttribute表示控制器屬于一個區(qū)域的一部分,即這個控制器是在 OMS 區(qū)域??刂破鞑粠Area] 特性則不屬于任何區(qū)域。

      ?

        當(dāng)在區(qū)域內(nèi)執(zhí)行操作時,區(qū)域的路由值將作為環(huán)境值以用于URL生成,這意味著,在默認(rèn)情況下,區(qū)域?qū)RL生成具有黏性:
      namespace Blog.Areas.OMS.Controllers { [Area("OMS")] public class
      OrderController : Controller {// GET: Order public ActionResult Index() { //
      生成/OManage/Home/Create var url = Url.Action("Create","Home"); //生成/Home/Create
      var url1 = Url.Action("Create", "Home",new { area=""}); return View(); } } }
      ?

      16.IActionConstraint

        通常應(yīng)用程序不需要自定義 IActionConstraint,[HttpGet] 特性以及類似的特性實現(xiàn)?IActionConstraint
      接口,以限制方法的執(zhí)行。


        當(dāng)兩個操作一模一樣,其中一個操作使用?IActionConstraint,總是認(rèn)為比沒有使用的操作更好,因為它被視為更加具體,并且兩個操作都可以在匹配是被選中。(沒有使用的操作會匹配任何HTTP謂詞)

        概念上,IActionConstraint
      是重載的一種形式,但不是使用相同名稱的重載,它是匹配相同URL操作的重載。特性路由也使用?IActionConstraint
      ,并且可以導(dǎo)致不同控制器的操作都被視為候選操作。

        實現(xiàn)?IActionConstraint 最簡單的方式是創(chuàng)建一個類派生自 System.Attribute
      ,并且將它放置到操作和控制器上。MVC會自動發(fā)現(xiàn)任何作為特性被應(yīng)用的
      IActionConstraint。你可以使用程序模型來應(yīng)用約束,可能是最靈活的方法,因為它允許對它們?nèi)绾伪粦?yīng)用進(jìn)行元編程。

        一個例子,一個約束選擇一個基于來自路由數(shù)據(jù)的 country code 操作:
      public class CountrySpecificAttribute:Attribute,IActionConstraint { private
      readonly string _countryCode; public CountrySpecificAttribute(string
      countryCode) { _countryCode= countryCode; } public int Order { get { return 0;
      } }public bool Accept(ActionConstraintContext context) { return string.Equals(
      context.RouteContext.RouteData.Values["country"].ToString(),
      _countryCode,StringComparison.OrdinalIgnoreCase); } }
        Accept 方法返回true,表示當(dāng)country路由值匹配時操作時匹配的。這個和 RouteValueAttribute
      不同,因為它允許回退到一個非特性操作。這個例子展示了如果定義一個 en-US 操作,然后國家代碼是
      fr-FR,則會回退到一個更通用的控制器,這個控制器沒有應(yīng)用 [CountrySpecific(...)] 。

        Order屬性和 [HttpGet] 特性中的Order屬性一樣,用來決定運行順序。

      ?

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          国产又爽 又黄 免费 | 人与野鲁交xxxx的视频 | 特级西西WWW444人体聚色 | 中文字幕一区二区三区西施Av | 久久精品影视大全 | 高清无码视频在线播放 | 美女伦理bd高清 韩日产理伦片在线观看 | 一区二区偷拍 | 韩国精品在线 | 秋霞影院午夜伦 |