精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

ASP.NET MVC控件項目開發的簡單分析

開發 后端
作者從一個ASP.NET MVC控件項目開始,對ASP.NET MVC控件進行了簡單的分析,十分深入透徹,希望對大家有所幫助。

【51CTO編者按】對于ASP.NET MVC框架大家一定不會陌生,但是對于很多人來說,弄好一個ASP.NET MVC控件項目實在是費勁的事情。這里由作者來介紹他的一個ASP.NET MVC控件項目經歷。51CTO編輯推薦《ASP.NET MVC框架視頻教程

在寫本文之前,本人一直抱著‘不宜’在ASP.NET MVC框架下搞什么控件開發的想法,因為一提到控件就會讓人想起‘事件’,‘VIEWSTATE’等一些問題,而ASP.NET MVC下是Controller, Action, Viewpage, Filter等特性的‘天下’。所以總感覺‘驢唇對不上馬嘴’。

但直到前陣子在郵箱中收到了關于telerik關于MVC框架擴展的一些信息之后,才發現這家商業控件公司也開始打MVC的主意了。而這個項目(開源)就是該公司在理解了asp.net mvc的基礎上所做的一些嘗試,當然其所實現的所謂控件與之前我們在項目中所開發或使用的web服務器控件有很大的不同,可以說是拋棄了以往的設計方式。盡管目前它的這種做法我心里還打著問號,但必定是一種嘗試(不管你贊同還是不贊同)。下面就做一個簡單的分析,希望能給研究MVC架構的朋友提供一些的思考。

首先要聲明的是該開源項目中所使用的js就是jquery,而那些顯示效果也基本上就是基于jQuery中的那件插件為原型,并進行相應的屬性封裝,以便于在viewpage中用C#等語言進行聲明綁定。下面就其中一些控件的顯示截圖:

控件的顯示截圖

控件顯示截圖

ASP.NET

進度條控件

在該開源項目中,所有控件均基于jQueryViewComponentBase (abstract 類型),但其自身屬性并不多,而所有的控件基類屬性都被jQueryViewComponentBase 的父類ViewComponentBase所定義,下面以控件中的“Accordion(屬性頁控件)”為例進行說明,見下圖:

Accordion(屬性頁控件)

上圖中左側的就是ViewComponentBase類,其定義了多數控件屬性,比如js腳本名稱和路徑以及相關樣式以及最終的html元素輸出方法,因為其類也是抽象類,所以其中大部分方法均為定義,而未進行具體實現。我們只要關注一下其構造方法就可以了:

  1. /// <summary> 
  2. /// View component base class.  
  3. /// </summary> 
  4.     public abstract class ViewComponentBase : IStyleableComponent, IScriptableComponent  
  5. {  
  6. private string name;  
  7. private string styleSheetFilesLocation;  
  8. private string scriptFilesLocation;  
  9. /// <summary> 
  10. /// 初始化相關Initializes a new instance of the <see cref="ViewComponentBase"/> class.  
  11. /// </summary> 
  12. /// <param name="viewContext">當前視圖的上下文,將會在子類中使用</param> 
  13. /// <param name="clientSideObjectWriterFactory">傳入當前所使用的Writer工廠實例.通過子類注入,子類最終延伸到相對應的控件實例</param> 
  14.         protected ViewComponentBase(ViewContext viewContext, IClientSideObjectWriterFactory clientSideObjectWriterFactory)  
  15. {  
  16. Guard.IsNotNull(viewContext, "viewContext");  
  17. Guard.IsNotNull(clientSideObjectWriterFactory, "clientSideObjectWriterFactory");  
  18. ViewContext = viewContext;  
  19. ClientSideObjectWriterFactory = clientSideObjectWriterFactory;  
  20. StyleSheetFilesPath = WebAssetDefaultSettings.StyleSheetFilesPath;  
  21. StyleSheetFileNames = new List<string>();  
  22. ScriptFilesPath = WebAssetDefaultSettings.ScriptFilesPath;  
  23. ScriptFileNames = new List<string>();  
  24. HtmlAttributes = new RouteValueDictionary();  
  25. }  

通過上述的構造方法,就可以將控件的一些通用默認屬性值進行初始化了。

下面以“Accordion”的源碼來分析一下,這里還是從構造方法入手:

  1. public class Accordion : jQueryViewComponentBase, IAccordionItemContainer  
  2. {  
  3. ……  
  4. /// <summary> 
  5. /// Initializes a new instance of the <see cref="Accordion"/> class.  
  6. /// </summary> 
  7. /// <param name="viewContext">The view context.</param> 
  8. /// <param name="clientSideObjectWriterFactory">The client side object writer factory.</param> 
  9.        public Accordion(ViewContext viewContext, IClientSideObjectWriterFactory clientSideObjectWriterFactory) : base(viewContext, clientSideObjectWriterFactory)  
  10. {  
  11. Items = new List<AccordionItem>();  
  12. autoHeight = true;  
  13. }  

注:上面的構程方法后面加入了base(viewContext, clientSideObjectWriterFactory),以實現向基類構造方法傳參,也就是實現了上面所說的將當前控件所使用的viewContext,clientSideObjectWriterFactory傳遞到基類ViewComponentBase 中去。(注:最終的clientSideObjectWriterFactory為ClientSideObjectWriterFactory實例類型)。

當然,因為該控件的中相應屬性比較簡單,只是一些set,get語法,所以就不過多介紹了,相信做過控件開發的對這些再熟悉不過了。

下面主要介紹一下其write html元素時所使用的方法,如下:

 

  1. /// <summary> 
  2. /// 創建并寫入初始化腳本對象和相應屬性.  
  3. /// </summary> 
  4. /// <param name="writer">The writer.</param> 
  5.       public override void WriteInitializationScript(TextWriter writer)  
  6. {  
  7. int selectedIndex = Items.IndexOf(GetSelectedItem());  
  8. IClientSideObjectWriter objectWriter = ClientSideObjectWriterFactory.Create(Id, "accordion", writer);  
  9. objectWriter.Start()  
  10. .Append("active", selectedIndex, 0)  
  11. .Append("animated", AnimationName)  
  12. .Append("autoHeight", AutoHeight, true)  
  13. .Append("clearStyle", ClearStyle, false)  
  14. .Append("collapsible", CollapsibleContent, false)  
  15. .Append("event", OpenOn)  
  16. .Append("fillSpace", FillSpace, false);  
  17. if (!string.IsNullOrEmpty(Icon) || !string.IsNullOrEmpty(SelectedIcon))  
  18. {  
  19. if (!string.IsNullOrEmpty(Icon) && !string.IsNullOrEmpty(SelectedIcon))  
  20. {  
  21. objectWriter.Append("icons:{'header':'" + Icon + "','headerSelected':'" + SelectedIcon + "'}");  
  22. }  
  23. else if (!string.IsNullOrEmpty(Icon))  
  24. {  
  25. objectWriter.Append("icons:{'header':'" + Icon + "'}");  
  26. }  
  27. else if (!string.IsNullOrEmpty(SelectedIcon))  
  28. {  
  29. objectWriter.Append("icons:{'headerSelected':'" + SelectedIcon + "'}");  
  30. }  
  31. }  
  32. objectWriter.Append("change", OnChange).Complete();  
  33. base.WriteInitializationScript(writer);  
  34. }  

可以看出,objectWriter (IClientSideObjectWriter 類型實例)中被綁定了相關的控件屬性,并通過其類的WriteInitializationScript(writer)進行腳本的輸出。而基本類的相應方法如下:    

  1.  /// <summary> 
  2. /// Writes the initialization script.  
  3. /// </summary> 
  4. /// <param name="writer">The writer.</param> 
  5.       public virtual void WriteInitializationScript(TextWriter writer)  
  6. {  
  7. }  

大家看到該方法為空,但其又是如何運行起來的呢,這里先賣個關子,稍后再說。接著再看一下另一個方法:WriteHtml()

  1. /// <summary> 
  2. /// 輸出當前的 HTML代碼.  
  3. /// </summary> 
  4.       protected override void WriteHtml()  
  5. {  
  6. AccordionItem selectedItem = GetSelectedItem();  
  7. TextWriter writer = ViewContext.HttpContext.Response.Output;  
  8. if (!string.IsNullOrEmpty(Theme))  
  9. {  
  10. writer.Write("<div class=\"{0}\">".FormatWith(Theme));  
  11. }  
  12. HtmlAttributes.Merge("id", Id, false);  
  13. HtmlAttributes.AppendInValue("class", " ", "ui-accordion ui-widget ui-helper-reset");  
  14. writer.Write("<div{0}>".FormatWith(HtmlAttributes.ToAttributeString()));  
  15. foreach (AccordionItem item in Items)  
  16. {  
  17. item.HtmlAttributes.AppendInValue("class", " ", "ui-accordion-header ui-helper-reset ui-state-default ");  
  18. item.ContentHtmlAttributes.AppendInValue("class", " ", "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom");  
  19. if (item == selectedItem)  
  20. {  
  21. item.ContentHtmlAttributes.AppendInValue("class", " ", "ui-accordion-content-active");  
  22. }  
  23. else  
  24. {  
  25. item.HtmlAttributes.AppendInValue("class", " ", "ui-corner-all");  
  26. }  
  27. writer.Write("<h3{0}><a href=\"#\">{1}</a></h3>".FormatWith(item.HtmlAttributes.ToAttributeString(), item.Text));  
  28. item.ContentHtmlAttributes.AppendInValue("style", ";", (item == selectedItem) ? "display:block" : "display:none");  
  29. writer.Write("<div{0}>".FormatWith(item.ContentHtmlAttributes.ToAttributeString()));  
  30. item.Content();  
  31. writer.Write("</div>");  
  32. }  
  33. writer.Write("</div>");  
  34. if (!string.IsNullOrEmpty(Theme))  
  35. {  
  36. writer.Write("</div>");  
  37. }  
  38. base.WriteHtml();  
  39. }  

該方法首先獲取當前所選屬性頁標簽(GetSelectedItem()方法),然后用foreach方法對屬性頁標簽集合進行遍歷,并判斷當前屬性頁是否就是被選中的屬性頁,并綁定上相應的css屬性。其最終也是調用相應的基類方法進行輸出。當然這里基類方法也是為空,呵呵。

準備好了這個控件類之后,Telerik還為Accordion控件‘準備’了一些輔助組件,比如屬性頁組件(AccordionItem),以及相關的組件構造器(AccordionItemBuilder,AccordionBuilder),這樣我們就可以通過這些構造器很方便的創建相應的控件和組件了,下面就以AccordionItemBuilder為例,解釋一下其構造器結構:

  1. public class AccordionBuilder : ViewComponentBuilderBase<Accordion, AccordionBuilder>, IHideObjectMembers  
  2. {  
  3. /// <summary> 
  4. /// 初始化方法Initializes a new instance of the <see cref="AccordionBuilder"/> class.  
  5. /// </summary> 
  6. /// <param name="component">The component.</param> 
  7.       public AccordionBuilder(Accordion component) : base(component)  
  8. {}  
  9. /// <summary> 
  10. /// 指定一個屬性頁選項  
  11. /// </summary> 
  12. /// <param name="addAction">要添加的action.</param> 
  13. /// <returns></returns> 
  14.       public virtual AccordionBuilder Items(Action<AccordionItemFactory> addAction)  
  15. {  
  16. Guard.IsNotNull(addAction, "addAction");  
  17. AccordionItemFactory factory = new AccordionItemFactory(Component);  
  18. addAction(factory);  
  19. return this;  
  20. }  
  21. /// <summary> 
  22. /// 屬性頁動態效果顯示名稱(鼠標在屬性頁移入移出時)  
  23. /// </summary> 
  24. /// <param name="effectName">Name of the effect.</param> 
  25. /// <returns></returns> 
  26.       public virtual AccordionBuilder Animate(string effectName)  
  27. {  
  28. Component.AnimationName = effectName;  
  29. return this;  
  30. }  
  31. /// <summary> 
  32. /// 是否高度自適用.  
  33. /// </summary> 
  34. /// <param name="value">if set to <c>true</c> value.</param> 
  35. /// <returns></returns> 
  36.       public virtual AccordionBuilder AutoHeight(bool value)  
  37. {  
  38. Component.AutoHeight = value;  
  39. return this;  
  40. }  
  41.  
  42. /// <summary> 
  43. /// 指定要觸發的屬性頁事件名稱.  
  44. /// </summary> 
  45. /// <param name="eventName">Name of the event.</param> 
  46. /// <returns></returns> 
  47.       public virtual AccordionBuilder OpenOn(string eventName)  
  48. {  
  49. Component.OpenOn = eventName;  
  50. return this;  
  51. }  
  52. /// <summary> 
  53. /// 所使用的Icons名稱.  
  54. /// </summary> 
  55. /// <param name="name">The name.</param> 
  56. /// <returns></returns> 
  57.       public virtual AccordionBuilder Icon(string name)  
  58. {  
  59. Component.Icon = name;  
  60. return this;  
  61. }  
  62. /// <summary> 
  63. /// 被選中的屬性頁所使用的Icons 名稱  
  64. /// </summary> 
  65. /// <param name="name">The name.</param> 
  66. /// <returns></returns> 
  67.       public virtual AccordionBuilder SelectedIcon(string name)  
  68. {  
  69. Component.SelectedIcon = name;  
  70. return this;  
  71. }  
  72. /// <summary> 
  73. /// 當屬性頁發生變化時要傳遞的action 腳本.  
  74. /// </summary> 
  75. /// <param name="javaScript">The java script.</param> 
  76. /// <returns></returns> 
  77.       public virtual AccordionBuilder OnChange(Action javaScript)  
  78. {  
  79. Component.OnChange = javaScript;  
  80. return this;  
  81. }  
  82. /// <summary> 
  83. /// Specify the name of the theme applies to the accordion.  
  84. /// </summary> 
  85. /// <param name="name">The name.</param> 
  86. /// <returns></returns> 
  87.       public virtual AccordionBuilder Theme(string name)  
  88. {  
  89. Component.Theme = name;  
  90. return this;  
  91. }  
  92. }  

對于上面的OnChange方法,可以使用下面的方法將相應的js腳本傳入并執行

  1. .OnChange(() => 
  2. {%> 
  3. function(event, ui)  
  4. {  
  5. $('#trace').append('Change fired: ' + new Date() + '<br/>');  
  6. }  
  7. <%}  
  8. )  

這樣,當屬性頁發生變化時,就會在頁面的指定區域將變化時間顯示出來了,如下圖:

屬性頁發生變化

Telerik在jQueryViewComponentFactory中對項目中每一個控件提供了一個方法用以初始化相應的構造器,以便于創建相應的控件,比如Accordion,形如: 

  1.  /// <summary> 
  2. /// Creates a accordion for ASP.NET MVC view.  
  3. /// </summary> 
  4. /// <returns></returns> 
  5.      [DebuggerStepThrough]  
  6. public virtual AccordionBuilder Accordion()  
  7. {  
  8. return new AccordionBuilder(Create(() => new Accordion(ViewContext, clientSideObjectWriterFactory)));  
  9. }  

而對于其在VIEW中的使用,則通過擴展方法來加以聲明:

  1. public static class HtmlHelperExtension  
  2. {  
  3. private static readonly IClientSideObjectWriterFactory factory = new ClientSideObjectWriterFactory();  
  4. /// <summary> 
  5. /// Gets the jQuery view components instance.  
  6. /// </summary> 
  7. /// <param name="helper">The html helper.</param> 
  8. /// <returns>jQueryViewComponentFactory</returns> 
  9.        [DebuggerStepThrough]  
  10. public static jQueryViewComponentFactory jQuery(this HtmlHelper helper)  
  11. {  
  12. return new jQueryViewComponentFactory(helper, factory);  
  13. }  
  14. }  

這樣在頁面視圖中,我們這可以使用下面的寫法來構造一個Accordion控件了:

  1. <% Html.jQuery().Accordion()  
  2. .Name("myAccordion")  
  3. .Animate("bounceslide")  
  4. .Items(parent => 
  5. ……  

上面只是介紹了前臺和底層代碼如果顯示的問題,但還沒有解釋之前所說的WriteInitializationScript(TextWriter writer)方法以及WriteHtml()
方法如何被調用的問題,正如之前所看到的,因為Accordion的基類ViewComponentBase中未實現具體的代碼,所以這里我們要將注意力轉移到 jQueryViewComponentFactory中,請看如下代碼: 

  1. private TViewComponent Create<TViewComponent>(Func<TViewComponent> factory) where TViewComponent : ViewComponentBase  
  2. {  
  3. TViewComponent component = factory();  
  4. if (component is jQueryViewComponentBase)  
  5. {  
  6. component.AssetKey = DefaultAssetKey;  
  7. }  
  8. htmlHelper.Telerik().StyleSheetRegistrar().ToRegistrar().Register(component);  
  9. htmlHelper.Telerik().ScriptRegistrar().ToRegistrar().Register(component);  
  10. return component;  
  11. }  

上面的方法其實就是之前在該類方法Accordion()中所調用并執行的:

  1. return new AccordionBuilder(Create(() => new Accordion(ViewContext, clientSideObjectWriterFactory))); 
通過該方法,就可以將該控件及其相關組件信息注冊到相應的視圖中。因為我們比較關注WriteHtml()方法,所以這里就直接分析一下這一行代碼:     
ScriptRegistrar().ToRegistrar().Register(component);
ScriptRegistrar類中的Register方法承擔著將當前要創建的組件添加到當前的腳本組件列表中的任務(scriptableComponents為list列表)    
  1.  
  2.        /// <summary> 
  3. /// Registers the scriptable component.  
  4. /// </summary> 
  5. /// <param name="component">The component.</param> 
  6.        public virtual void Register(IScriptableComponent component)  
  7. {  
  8. Guard.IsNotNull(component, "component");  
  9. if (!scriptableComponents.Contains(component))  
  10. {  
  11. scriptableComponents.Add(component);  
  12. }  
  13. }  

當組件被成功添加到該list列表中后,系統就會調用Render()方法將其顯示出來(注:該方法與以前web控件開發中的顯示方法同名,所以比較好理解),如下:   

  1.     /// <summary> 
  2. /// Writes the scripts in the response.  
  3. /// </summary> 
  4.       public void Render()  
  5. {  
  6. if (hasRendered)  
  7. {  
  8. throw new InvalidOperationException(Resources.TextResource.YouCannotCallRenderMoreThanOnce);  
  9. }  
  10. if (ViewContext.HttpContext.Request.Browser.EcmaScriptVersion.Major >= 1)  
  11. {  
  12. Write(ViewContext.HttpContext.Response.Output);  
  13. }  
  14. hasRendered = true;  
  15. }  

注意上面的這一行代碼:

Write(ViewContext.HttpContext.Response.Output);

其所實現的功能如下:  

  1.     /// <summary> 
  2. /// 寫出所有腳本資源和腳本 statements.  
  3. /// </summary> 
  4. /// <param name="writer">The writer.</param> 
  5.       protected virtual void Write(TextWriter writer)  
  6. {  
  7. WriteScriptSources(writer);  
  8. WriteScriptStatements(writer);  
  9. }  

而就是WriteScriptStatements這行代碼開始執行之前所說的那個WriteInitializationScript(TextWriter writer)。而WriteHtml()方法的執行入口要更加復雜一些,因為Telerik提供了ViewComponentBuilderBase這個類來進行視圖組件的構造,而該類中的Render方法就是對相應組件的Render方法(組件中已定義)進行調用,如下:

  1.     /// <summary> 
  2. /// Renders the component.  
  3. /// </summary> 
  4.     public virtual void Render()  
  5. {  
  6. Component.Render();  
  7. }  

而之前的“Accordion”控件是繼承自ViewComponentBase類,所以相應組件的Render方法就在該類中進行了聲明定義,如下:

  1.   /// <summary> 
  2. /// Renders the component.  
  3. /// </summary> 
  4.      public void Render()  
  5. {  
  6. EnsureRequired();  
  7. WriteHtml();  
  8. }  

大家看到了第二行代碼了吧,這就是我們之前看到的那個方法,也就是Accordion組件中WriteHtml()重寫方法的調用入口。

繞了這么一大圈,才把這個流程理清,是不是有些暈了。的確,剛開始接觸時我也有點暈,但暈呀暈呀就‘暈過去了’,現在再回頭看起來感常見其整體的架構思路還是很清晰的。可以說有了這瓶酒墊底,再分析該項目中的其它控件就‘如魚得水’了。

***不妨總結一下:

這是對ASP.NET MVC控件項目開發做的一次嘗試,但如果之前做過控件特別是web服務器端控件開發的朋友,可以看出項目中有非常重的web控件開發味道,基本連方法名稱都有一定的重疊。

另外就是其自身還是引用了組件對象模型的概念,就拿屬性頁控件來說,就將其分為Accordion和AccordionItem兩種類型,其中可以將Accordion看成是AccordionItem的集合封裝(包括遍歷操作),而這里AccordionItem就成了Accordion的一個組件,而Accordion又是當前view中的一個組件。而組件開發一直是.NET平臺上所倡導的。其優勢在于可復用,維護方便,簡化復雜問題等。

原文標題:一個Asp.net MVC 控件項目分析---Telerik.Web.Mvc

鏈接:http://www.cnblogs.com/daizhj/archive/2009/09/09/1562966.html

【編輯推薦】

  1. 點評一下ASP.NET的WEB控件
  2. ASP.NET控件學習總結
  3. ASP.NET前臺控件點評:避免強迫癥,奔向簡潔高效
  4. ASP.NET 2.0環境下的Shell函數
  5. 在ASP.NET 2.0中向數據庫批量插入數據
責任編輯:彭凡 來源: 博客園
相關推薦

2009-07-28 14:47:18

ASP.NET MVC

2009-08-04 10:43:59

ASP.NET控件開發

2009-08-07 15:24:16

ASP.NET模板控件

2009-03-13 10:58:48

ASP.NetMVC框架編程

2009-07-31 12:43:59

ASP.NET MVC

2009-07-24 13:20:44

MVC框架ASP.NET

2014-06-30 09:22:38

ASP.NETBootstrap

2009-04-20 09:43:37

ASP.NET MVC基礎開發

2009-07-27 13:52:36

Panel控件ASP.NET

2009-07-29 09:04:36

JQRTEasp.net mvc

2009-07-24 15:46:00

ASP.NET登陸控件

2009-08-04 12:59:42

ASP.NET控件開發

2009-08-07 14:42:02

ASP.NET控件開發

2011-07-12 15:17:02

ASP.net服務器控件

2009-08-07 15:34:15

ASP.NET數據綁定

2009-08-06 18:18:27

ASP.NET控件開發ASP.NET復合控件

2009-07-20 15:44:32

ASP.NET MVC

2009-07-22 09:11:02

Action方法ASP.NET MVC

2009-07-22 10:34:37

ActionInvokASP.NET MVC

2009-07-29 02:40:00

asp.net mvc
點贊
收藏

51CTO技術棧公眾號

超碰10000| 亚洲自拍欧美色图| 亚洲黄色免费视频| av在线国产精品| 亚洲一区二区精品久久av| 精品欧美日韩在线| 中文字幕在线观看免费| 欧美激情视频一区二区三区免费| 精品亚洲一区二区三区在线播放| 亚洲 欧美 另类人妖| 女人天堂av在线播放| 久久伊人中文字幕| 亚洲自拍偷拍色片视频| 久久精品久久久久久久| 午夜日韩激情| 一本一道久久a久久精品逆3p| 久久久福利影院| av日韩亚洲| 亚洲制服丝袜av| 亚洲一区二区三区午夜| 头脑特工队2在线播放| 极品美女销魂一区二区三区 | 久久九九国产| 久久99精品久久久久久青青91 | 亚洲精品综合网| 日韩成人免费电影| 海角国产乱辈乱精品视频| 国精产品视频一二二区| 久久99影视| 亚洲国产中文字幕在线观看| 日韩av加勒比| 国产成人77亚洲精品www| 欧美日韩亚洲一区二| 日韩一级特黄毛片| 久操视频在线观看| 欧美国产日产图区| 欧美xxxx黑人又粗又长精品| 欧美 日韩 国产 在线| 国产精品18久久久久久久久| 国产精品亚洲综合天堂夜夜| 久久国产黄色片| 亚洲精品护士| 久久久久国产精品免费网站| 精品国产视频在线观看| 91亚洲国产| 色婷婷综合久久久久| 人人爽人人爽人人片| 黑人操亚洲人| 在线亚洲午夜片av大片| 国产伦精品一区二区三区视频女| 国产一区二区三区四区五区传媒| 国产婷婷色综合av蜜臀av| 男女一区二区三区| 久久悠悠精品综合网| 亚洲国产精品va在线看黑人| 欧美日韩一区二区三区四区五区六区| 香蕉大人久久国产成人av| 欧美成人vr18sexvr| 欧美性猛交乱大交| 成人福利免费在线观看| 日韩的一区二区| 国产激情在线免费观看| 欧美欧美黄在线二区| 亚洲天堂男人天堂女人天堂| 乐播av一区二区三区| 日本女优一区| 久久久成人的性感天堂| 午夜69成人做爰视频| 国产综合久久| 欧美一级电影久久| 日批视频免费在线观看| 免费在线视频一区| 91黄色精品| 天天操天天舔天天干| 久久夜色精品国产欧美乱极品| 日本不卡二区| 久cao在线| 五月婷婷色综合| 老熟妇仑乱视频一区二区| 青青国产精品| 欧美大胆人体bbbb| 免费在线观看成年人视频| jvid福利在线一区二区| 久久伊人色综合| 五月天婷婷网站| 日韩二区三区在线观看| 亚洲xxxx18| 日本私人网站在线观看| 中文字幕一区二区三区不卡在线 | 92久久精品| 在线免费观看日本欧美| 黑人性生活视频| 无码日韩精品一区二区免费| 日韩在线视频网| 日韩网红少妇无码视频香港| 免费人成在线不卡| 国产精品久久久久久免费观看 | 一道本一区二区三区| 少妇激情综合网| 日本三级中文字幕| 久久精品国产精品亚洲红杏| 国产91视觉| av中文资源在线| 亚洲成人av电影| 日本肉体xxxx裸体xxx免费| 国产三级精品三级在线观看国产| 国产一区二区三区在线视频| 久久久久久久国产精品毛片| 日本中文字幕一区二区有限公司| 超碰97网站| 日韩精品毛片| 欧美视频中文在线看| 樱花草www在线| 精品不卡一区| 668精品在线视频| www久久久久久| 国产精品久久久久久久蜜臀 | 亚洲电影免费观看高清| 林心如三级全黄裸体| 亚洲一区二区三区四区五区午夜| 亚洲free性xxxx护士hd| 成人免费黄色网页| 日韩欧美大尺度| bl动漫在线观看| 午夜精品亚洲| 91久久精品www人人做人人爽| 国内三级在线观看| 红桃视频成人在线观看| 韩国一区二区三区四区| 性欧美欧美巨大69| 国产精品偷伦免费视频观看的| 日本在线视频1区| 午夜私人影院久久久久| av电影中文字幕| 亚洲草久电影| 亚洲va欧美va在线观看| 毛片在线播放a| 欧美日韩国产bt| 99久久99久久精品免费看小说.| 香蕉视频成人在线观看| 精品久久久三级| 久久影院午夜精品| 日韩久久精品成人| 欧美 日韩 精品| 国产亚洲欧美日韩在线一区| 精品久久久久久久免费人妻| 神马久久影院| 国产精品aaaa| 欧美极品视频| 日韩一级成人av| 久久成人国产精品入口| 粉嫩在线一区二区三区视频| 屁屁影院ccyy国产第一页| 精品视频一二| 久久久久久久久久久久av| 亚洲国产精品suv| 性感美女极品91精品| 中国极品少妇videossexhd| 亚洲尤物影院| 亚洲精蜜桃久在线| 亚洲精品第一| 欧美激情综合色| 少妇一级淫片免费看| 日韩欧美福利视频| 啪啪一区二区三区| 福利视频网站一区二区三区| 久操网在线观看| 在线日韩网站| 国产在线视频2019最新视频| 中文av资源在线| 亚洲精品国产美女| 波多野结衣视频网址| 成人免费视频在线观看| 佐佐木明希电影| 亚洲欧美久久久| 在线精品亚洲一区二区| 一区二区三区亚洲变态调教大结局 | 在线播放免费av| 日韩精品亚洲视频| 中文字幕在线观看国产| 亚洲一区二区三区自拍| 美女被到爽高潮视频| 国产麻豆欧美日韩一区| 奇米精品一区二区三区| 成人精品影视| 国产高清在线一区二区| xx欧美视频| 久久夜色精品国产亚洲aⅴ| 五月婷婷六月色| 欧美日本不卡视频| 国产精品久久久久久久妇| 国产精品麻豆99久久久久久| 日本精品一二三| 日本成人超碰在线观看| 日本一区午夜艳熟免费| 欧洲激情综合| 国产区一区二区三区| 日韩一区二区三免费高清在线观看| 九九热这里只有在线精品视| 国产一区二区影视| 亚洲精品在线网站| 97视频免费在线| 日韩欧亚中文在线| 久久久久亚洲av片无码下载蜜桃 | 一区二区视频国产| 性人久久久久| 99视频在线免费观看| 成人亚洲免费| 热久久这里只有精品| 蜜桃传媒在线观看免费进入| 日韩在线激情视频| 人成在线免费视频| 日韩免费一区二区| 国产精品高潮呻吟久久久| 色偷偷久久一区二区三区| 精品自拍偷拍视频| 日本一区二区三区在线不卡| 日本一卡二卡在线| 国产91精品免费| 91插插插影院| 麻豆精品一区二区综合av| 国产亚洲精品网站| 中日韩视频在线观看| 久久久久久久久久伊人| 日韩av有码| 日韩欧美三级一区二区| 午夜欧洲一区| 精品国产一区二区三| 一本色道69色精品综合久久| 亚洲自拍高清视频网站| 国产成年精品| 亚洲精品欧美日韩| 国产精品高清一区二区| 国产美女扒开尿口久久久| 一呦二呦三呦精品国产| 青草青草久热精品视频在线观看| 欧美办公室脚交xxxx| 性欧美xxxx视频在线观看| 天堂av资源在线观看| 久久精品视频播放| 国产精品久久麻豆| 久久国产精品久久国产精品| 免费网站成人| 麻豆国产精品va在线观看不卡| 欧美日韩在线看片| 久久精品久久久久久| av黄在线观看| 色综合久久88| 国产美女情趣调教h一区二区| 欧美高清一级大片| 国产美女精品写真福利视频| 91成人免费观看网站| www.日韩| 国产日韩欧美在线看| 国产精品亚洲欧美一级在线| 91老司机在线| 综合视频一区| 国产亚洲精品美女久久久m| 日韩人体视频| 色噜噜狠狠色综合网| 欧美丰满日韩| 国产专区在线视频| 99精品国产福利在线观看免费| 97av视频在线观看| 蜜臀精品一区二区三区在线观看 | 精品国产一区二区三区在线观看| 美女写真理伦片在线看| 久久久久久亚洲精品| 中文在线中文资源| 国产精品一二区| 日韩三级精品| 欧美性大战久久久久| 久久国产小视频| 中国丰满熟妇xxxx性| 天堂久久久久va久久久久| 极品粉嫩美女露脸啪啪| 盗摄精品av一区二区三区| 精品久久久久久中文字幕人妻最新| 欧美激情一区在线观看| 欧美国产日韩综合| 欧美午夜片在线免费观看| 亚洲视频一区二区三区四区| 日韩视频一区二区| 免费在线黄色影片| 不卡av在线播放| 美女100%一区| 91超碰rencao97精品| 亚洲最好看的视频| av磁力番号网| 亚洲欧美日韩国产一区| www.色.com| 国产亚洲欧洲997久久综合| 日本黄色小说视频| 一本色道综合亚洲| 成人激情四射网| 国产亚洲精品日韩| 9lporm自拍视频区在线| 国产精品视频yy9099| 久久久久久毛片免费看| 一区二区三视频| 丝袜诱惑制服诱惑色一区在线观看| 在线免费看v片| 国产亚洲欧美日韩俺去了| 国产精品99无码一区二区| 欧美日韩免费高清一区色橹橹| 日日夜夜精品免费| 久久国产精品久久精品| 久久99久久久精品欧美| 六月婷婷久久| 亚洲国内自拍| 亚洲少妇一区二区| 中文字幕亚洲欧美在线不卡| 91精品国产综合久久久蜜臀九色| 日韩精品在线网站| 三区四区电影在线观看| 国产精品igao视频| 欧美91在线| 久久综合久久久久| 国产一区欧美日韩| 国产激情av在线| 色香蕉久久蜜桃| 欧美男男同志| 欧美亚洲一级片| 中文无码日韩欧| 欧美 另类 交| 日韩av网站免费在线| 免费在线观看你懂的| 五月天丁香久久| 免费成人在线看| 欧美寡妇偷汉性猛交| 视频精品一区二区三区| 国产又黄又爽免费视频| 久久狠狠亚洲综合| 91av手机在线| 欧美日韩不卡一区| 五月婷婷在线观看| 成人免费观看网址| 影音先锋日韩在线| 一本之道在线视频| 亚洲精品国产第一综合99久久 | 国产另类ts人妖一区二区| 免费在线观看黄色小视频| 欧美日韩中字一区| a天堂在线资源| 国产日本欧美视频| 国产精品99在线观看| 亚洲色图欧美自拍| 夜夜嗨av一区二区三区网页 | 久久国产成人精品国产成人亚洲| 成人一区二区三区视频在线观看| 欧美日韩免费做爰视频| 精品国一区二区三区| av在线网页| 精品毛片久久久久久| 欧美中文日韩| 国产精品久久久久久久av| 欧美日韩在线免费视频| 精品美女在线观看视频在线观看 | 亚洲三级网页| 日本新janpanese乱熟| 国产精品久久久久婷婷二区次| 国产乱淫av片免费| 国内久久久精品| 自拍视频一区| 中文字幕第17页| 亚洲一级电影视频| 日韩午夜影院| 国产精品永久免费| 欧美午夜一区二区福利视频| 日本五十肥熟交尾| 日本韩国精品在线| 欧美精品电影| 国内成+人亚洲| 日本一不卡视频| 国产一级av毛片| 亚洲社区在线观看| 成人影院网站ww555久久精品| 日韩精品一区二区免费| 91论坛在线播放| 国产又粗又猛视频| 91国偷自产一区二区三区的观看方式| 日本一区福利在线| 中文字幕av专区| 亚洲一区二区综合| 9色在线观看| 国产精品久久久对白| 日韩精品亚洲一区二区三区免费| 麻豆明星ai换脸视频| 日韩成人小视频| 高清不卡一区| 少妇性l交大片| 亚洲最色的网站| 91大神xh98hx在线播放| 国产精品久久久对白| 蓝色福利精品导航| 在线精品免费视| 久精品免费视频| 色琪琪久久se色| 野花社区视频在线观看| 欧美一区二区视频免费观看|