精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

午夜啪啪小视频| 污视频在线免费观看一区二区三区| 永久免费看黄网站| 亚洲视频精选| 亚洲国产一二三| 日本欧洲国产一区二区| 国产成人av免费看| 男女精品网站| 蜜月aⅴ免费一区二区三区| 完美搭档在线观看| 日韩城人网站| 欧美体内谢she精2性欧美| 国产成年人在线观看| 女人18毛片一区二区三区| 日本va欧美va瓶| 国产做受69高潮| 国产探花在线视频| 亚洲69av| 亚洲成av人片在线观看香蕉| 亚洲欧美自拍另类日韩| 第一福利在线视频| 最新国产精品久久精品| 久久免费看av| 亚洲精品成av人片天堂无码| 麻豆国产欧美日韩综合精品二区 | 日韩免费啪啪| 2017欧美狠狠色| 99视频免费观看| 伊人免费在线观看| 亚洲欧美网站| 97人人模人人爽人人喊中文字| 中国毛片直接看| 日本不卡高清| 一本色道久久88亚洲综合88| 亚洲av网址在线| 成人自拍在线| 日韩视频国产视频| 搡的我好爽在线观看免费视频| 国产韩日精品| 欧美艳星brazzers| 国产福利一区视频| 成人美女视频| 色婷婷综合中文久久一本| 国产二级片在线观看| 久久青青色综合| 一区二区三区欧美视频| ijzzijzzij亚洲大全| 久久亚洲天堂| 亚洲欧美日韩国产综合| 中文字幕久精品免| 成人毛片av在线| 亚洲男女一区二区三区| 黑人巨大国产9丨视频| 久久精品视频观看| 亚洲欧洲综合另类在线| 一二三在线视频| 中文字幕伦理免费在线视频 | 青草视频在线观看免费| 一区二区三区成人精品| 97婷婷大伊香蕉精品视频| 国产福利拍拍拍| 亚洲在线成人| 国产精品黄色影片导航在线观看| www.com亚洲| 日韩av网站免费在线| 国产美女精品视频免费观看| 国产精品嫩草影院精东| 国产成人精品三级麻豆| 国产精品视频入口| 亚洲aaa在线观看| 久久精品视频一区| 一本一道久久a久久精品综合| 国产欧美黑人| 亚洲大片精品永久免费| 六月丁香婷婷激情| 亚洲精品555| 日韩欧美一区在线| 欲求不满的岳中文字幕| 天堂日韩电影| 日韩在线视频观看| 国产一级aa大片毛片| 亚洲综合精品| 91九色视频导航| 黑人精品一区二区| 欧美国产欧美综合| av一区二区三区免费观看| 在线天堂资源| 欧美一区二区三区小说| 鲁大师私人影院在线观看| 欧美一区二区麻豆红桃视频| 欧美剧在线观看| 日本韩国欧美中文字幕| 黄一区二区三区| 国产亚洲欧美另类一区二区三区| 国产玉足榨精视频在线观看| 亚洲美腿欧美偷拍| 日韩欧美视频网站| 亚洲狼人综合| 国产丝袜视频一区| 蜜臀久久精品久久久用户群体| 在线日韩中文| 91精品视频在线免费观看| 天天爽夜夜爽夜夜爽| 中文字幕中文字幕中文字幕亚洲无线| 欧美亚洲黄色片| 祥仔av免费一区二区三区四区| 日韩av中文字幕在线| 日韩三级在线观看视频| 久久午夜视频| 国产精品日韩一区二区| 哥也色在线视频| 欧洲色大大久久| 亚洲精品无码一区二区| 欧美独立站高清久久| 51午夜精品视频| www.国产麻豆| 国产精品久久久久久久久免费丝袜 | 毛毛毛毛毛毛毛片123| 最新国产一区| 91精品国产91久久久久久吃药| 一区二区精品视频在线观看| 久久香蕉国产线看观看99| 成人免费网站入口| 国产亚洲高清一区| 中文字幕精品一区久久久久 | 91.com视频| 精品人妻一区二区三区蜜桃视频| 一区在线视频观看| 亚洲一区中文字幕在线观看| 香港伦理在线| 欧美亚洲自拍偷拍| 国产黄片一区二区三区| 国产精品日韩精品欧美精品| 鬼打鬼之黄金道士1992林正英| 欧美性天天影视| 欧美视频中文字幕| 永久免费毛片在线观看| 日韩av成人高清| 蜜桃999成人看片在线观看| a在线视频v视频| 亚洲福利影片在线| 精品一区在线视频| 懂色av一区二区夜夜嗨| 久久艹国产精品| 综合伊人久久| 97久久精品国产| 亚洲色图欧美视频| 日韩欧美在线观看视频| 9.1成人看片免费版| 久久亚洲精选| 神马影院午夜我不卡| 懂色aⅴ精品一区二区三区| 色哟哟网站入口亚洲精品| 伊人成人在线观看| 最新中文字幕一区二区三区| 少妇高潮一69aⅹ| 国产一区二区三区四区老人| 国产精品av一区| 国产资源在线观看入口av| 日韩成人在线免费观看| 日本免费在线观看视频| 国产农村妇女精品| 一区二区三区入口| 久久久久免费av| 99精品国产高清在线观看| h片在线观看视频免费免费| 亚洲黄在线观看| 波多野结衣小视频| 成人免费在线播放视频| 中文字幕无人区二| 国产精品亚洲欧美| 亚洲韩国在线| 欧洲大片精品免费永久看nba| 欧美激情2020午夜免费观看| 天堂在线视频网站| 欧美视频在线观看一区二区| 国产a免费视频| 26uuu国产电影一区二区| 欧美三级理论片| 91精品久久久久久久蜜月| 国产精品国产亚洲精品看不卡15 | 国产视频在线播放| 日韩成人在线观看| 在线黄色av网站| 亚洲尤物在线视频观看| 99久久久无码国产精品性| 久久er99热精品一区二区| 日韩xxxx视频| 狠狠操综合网| 国产精品福利视频| 国产精品高潮久久| 国内精品久久久久伊人av| 国产精品一区二区婷婷| 日韩欧美视频一区| 无码人妻丰满熟妇精品 | 日本道在线视频| 亚洲精品456| 51国偷自产一区二区三区| 黑人巨大精品| 欧美极品少妇xxxxⅹ裸体艺术| 国产经典自拍视频在线观看| 欧美成va人片在线观看| 亚洲中文一区二区三区| 性久久久久久久| 免费黄色激情视频| 久久美女高清视频| 日韩大尺度视频| 麻豆国产精品官网| 国产主播在线看| 在线观看日韩av电影| 亚洲综合欧美日韩| 视频福利一区| 国产精品毛片一区视频| 日本午夜免费一区二区| 日韩av电影在线播放| 成人免费高清观看| 久久久www成人免费精品| 国产原创av在线| 亚洲欧美第一页| 性猛交xxxx乱大交孕妇印度| 欧美精品久久天天躁| 波多野结衣视频免费观看| 狠狠综合久久av一区二区小说| 久久这里只有精品国产| 中文字幕在线不卡视频| 一区二区三区在线观看免费视频| 国产成人精品一区二| 午夜影院免费观看视频| 老司机精品视频一区二区三区| 国产av无码专区亚洲精品| 亚洲精品欧美| 免费无码毛片一区二三区| 欧美视频二区| 无码人妻精品一区二区蜜桃百度| 99久久精品费精品国产| 亚洲视频sss| 精品国产一区二区三区久久久蜜臀| 国产一区在线免费| 精品欠久久久中文字幕加勒比| 国产精品12| 国产女人18毛片水真多18精品| 成人影片在线播放| 成人香蕉社区| 黑人巨大精品欧美一区二区小视频 | 91精品久久久久久粉嫩| 久久天天躁狠狠躁老女人| 免费在线观看av网站| www亚洲欧美| 成人短视频在线观看| 九九精品在线视频| 日本乱理伦在线| 高清视频欧美一级| 麻豆免费在线| 日韩美女主播视频| 欧美与亚洲与日本直播| 国产精品永久免费视频| 亚洲伦理久久| 国产精品区一区| 一本色道久久综合狠狠躁的番外| 欧美另类网站| 日韩一区二区在线免费| 99热这里只有精品7| 欧美网站在线| 91精品国产91久久久久麻豆 主演| 亚洲国产三级| 国产成人精品视频ⅴa片软件竹菊| 日韩国产精品久久久| www.se五月| 国产精品中文字幕一区二区三区| youjizz.com日本| 久久在线免费观看| 亚洲色图欧美色| 亚洲精品国产成人久久av盗摄 | 日韩福利电影在线观看| 国产欧美一区二| 成人av在线一区二区三区| ass精品国模裸体欣赏pics| 国产日产亚洲精品系列| 国产一区二区视频在线观看免费| 午夜激情久久久| 一区二区三区在线免费观看视频| 欧美电视剧在线看免费| 日本黄在线观看| 久久精品小视频| 日韩理论视频| 成人免费网站在线| 色吊丝一区二区| 欧美 日韩 国产 在线观看| 99热这里只有精品8| 奇米影视四色在线| av在线播放成人| 999福利视频| 精品久久香蕉国产线看观看亚洲| 亚洲天堂aaa| 亚洲国产一区自拍| 国产激情视频在线观看| 欧美最猛性xxxxx亚洲精品| www.91精品| 女人一区二区三区| 狠狠爱www人成狠狠爱综合网| 无码无遮挡又大又爽又黄的视频| 国产精品乡下勾搭老头1| 右手影院亚洲欧美| 伊人开心综合网| 中文字幕+乱码+中文字幕明步| 精品福利在线导航| 麻豆传媒在线观看| 日本视频久久久| 哺乳挤奶一区二区三区免费看| 日韩欧美99| 国产日韩1区| zjzjzjzjzj亚洲女人| 国产精品久久久久久久久免费樱桃 | 午夜一级久久| 韩国av中国字幕| 国产精品福利影院| 激情视频网站在线观看| 亚洲国产精品yw在线观看| 岛国中文字幕在线| 国产精品女人久久久久久| 女人抽搐喷水高潮国产精品| 国产乱子伦精品无码专区| 韩国成人福利片在线播放| 中文字幕网站在线观看| 欧美性生交大片免网| 四虎精品一区二区三区| 久久久久久久电影一区| 天堂av一区| 男人添女人下部视频免费| 精品在线一区二区三区| 2017亚洲天堂| 欧美日韩成人在线一区| av中文在线| 国产精品久久久久久久久久三级 | av男人天堂一区| 久久精品国产亚洲av高清色欲| 欧美一区二区在线免费观看| 欧美r级在线| 91美女片黄在线观| 亚洲国产精品成人| 青娱乐精品在线| 亚洲欧美福利一区二区| 国产av精国产传媒| 毛片精品免费在线观看| 精品国产麻豆| 久久久久久久久久久久久国产| 国产一区二区中文字幕| 欧美日韩精品亚洲精品| 欧美成人bangbros| 玖玖在线播放| 欧美日韩一区在线视频| 日韩影院在线观看| 国产激情av在线| 欧美日本在线观看| 菠萝菠萝蜜在线观看| 999视频在线观看| 伊人激情综合| 国产精品亚洲无码| 欧美系列亚洲系列| 高潮毛片在线观看| 成人片在线免费看| 国产一区二区你懂的| 高清国产在线观看| 4438成人网| 密臀av在线| 欧美资源一区| 久久爱www久久做| 久久久久久激情| 亚洲欧洲日本专区| 性欧美video另类hd尤物| 特大黑人娇小亚洲女mp4| 不卡av在线网| 波多野结衣视频观看| 欧美精品午夜视频| 狼人天天伊人久久| 日韩精品视频一二三| 亚洲精品欧美在线| 日韩福利一区二区| 国产在线精品播放| 激情欧美亚洲| 极品久久久久久久| 亚洲成人网久久久| 深夜视频一区二区| 黄色网在线视频| 久久久久久97三级| 国产草草影院ccyycom| 日本一本a高清免费不卡| 伊人久久大香线| 女人被狂躁c到高潮| 91精品综合久久久久久| 亚洲精品88| 欧美日韩视频免费在线观看| 91视频国产资源| 国产av精国产传媒| 国产精品三级久久久久久电影| 精品电影一区| 日本福利片在线观看| 亚洲女人被黑人巨大进入al| 天堂久久av| 日韩精品你懂的|