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

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

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

      通過(guò)實(shí)例模擬ASP.NET MVC的Model綁定機(jī)制:數(shù)組

      [續(xù)《通過(guò)實(shí)例模擬ASP.NET MVC的Model綁定機(jī)制:簡(jiǎn)單類(lèi)型+復(fù)雜類(lèi)型]》]基于數(shù)組和集合類(lèi)型的Model綁定機(jī)制比較類(lèi)似,對(duì)于綁定參數(shù)類(lèi)型或者參數(shù)類(lèi)型的某個(gè)屬性為數(shù)組或者集合,如果ValueProvider根據(jù)對(duì)應(yīng)的Key能夠匹配多條數(shù)據(jù),那么這些數(shù)據(jù)最終將會(huì)轉(zhuǎn)換為綁定的數(shù)組/集合的元素。此外,針對(duì)數(shù)組/集合的Model綁定還支持基于索引的方式。[源代碼從這里下載][本文已經(jīng)同步到《How ASP.NET MVC Works?》中]

      一、基于名稱(chēng)的數(shù)組綁定

      對(duì)于針對(duì)NameValueConllectionProvider來(lái)說(shuō),通過(guò)GetValue方法得到的ValueProviderResult的RawValue總是一個(gè)字符串?dāng)?shù)組(不論是否具有多條數(shù)據(jù)于指定的Key相匹配,如果只有一條匹配的數(shù)據(jù),RawValue就是一個(gè)具有一個(gè)元素的字符串?dāng)?shù)組)。當(dāng)我們調(diào)用ValueProviderResult的ConvertTo方法將提供的值轉(zhuǎn)換成某種類(lèi)型時(shí),如果目標(biāo)類(lèi)型是數(shù)組或者集合,那么RawValue代表的字符串?dāng)?shù)組元素將會(huì)轉(zhuǎn)換成目標(biāo)對(duì)象的元素;如果目標(biāo)類(lèi)型不屬于集合,那么參與數(shù)據(jù)轉(zhuǎn)換的僅僅是RawValue數(shù)組的第1個(gè)元素。

      如下面的代碼片斷所示,在默認(rèn)的HomeController的默認(rèn)Action方法Index中,我們創(chuàng)建了一個(gè)NameValueCollectionValueProvider對(duì)象,作為數(shù)據(jù)源的NameValueCollection中包含了三個(gè)同名(foo)數(shù)據(jù)條目。我們調(diào)用它的GetValue方法得到一個(gè)ValueProviderResult對(duì)象,然后我們將該對(duì)象的RawValue呈現(xiàn)出來(lái)。最后我們調(diào)用該ValueProviderResult對(duì)象的ConvertTo對(duì)象將提供的值轉(zhuǎn)換為int[]和int,并將轉(zhuǎn)換后的值呈現(xiàn)出來(lái)。

         1: public class HomeController : Controller
         2: {
         3:     public void Index()
         4:     {        
         5:         NameValueCollection dataSource = new NameValueCollection();
         6:         dataSource.Add("foo", "123");
         7:         dataSource.Add("foo", "456");
         8:         dataSource.Add("foo", "789");
         9:         NameValueCollectionValueProvider valueProvider = new NameValueCollectionValueProvider(dataSource, CultureInfo.InvariantCulture);
        10:  
        11:         ValueProviderResult result = valueProvider.GetValue("foo");
        12:         Response.Write(string.Format("RawValue: {0}<br/>", result.RawValue));
        13:         Response.Write(string.Format("ConvertTo(typeof(int[])): {0}<br/>", result.ConvertTo(typeof(int[]))));
        14:         Response.Write(string.Format("ConvertTo(typeof(int)): {0}<br/>", result.ConvertTo(typeof(int))));
        15:     }
        16: }

      運(yùn)行這個(gè)程序之后,我們會(huì)在瀏覽器中得到如下的輸出結(jié)果,上面針對(duì)NameValueConllectionProvider的論述可以從輸出結(jié)果中得到印證。

         1: RawValue: System.String[]
         2: ConvertTo(typeof(int[])): System.Int32[]
         3: ConvertTo(typeof(int)): 123

      NameValueConllectionProvider(FormValueProvider和QueryStringValueProvider)的數(shù)據(jù)值提供機(jī)制決定了Model綁定的默認(rèn)行為。如果綁定的目標(biāo)對(duì)象是一個(gè)數(shù)組或者集合,匹配的同名數(shù)據(jù)項(xiàng)將會(huì)作為目標(biāo)對(duì)象的元素。實(shí)際上HttpFileCollectionValueProvider的數(shù)據(jù)值提供機(jī)制也類(lèi)似,如果綁定的目標(biāo)對(duì)象類(lèi)型是一個(gè)HttpPostedFileBase數(shù)組,那么匹配的同名文件輸入元素都將作為其數(shù)據(jù)源。

         1: <input name="Foo" type="text" ... />
         2: <input name="Foo" type="text" ... />
         3: <input name="Foo" type="text" ... />
         4: <input name="Bar" type="file" ... /> 
         5: <input name="Bar" type="file" ... />
         6: <input name="Bar" type="file" ... />

      假設(shè)針對(duì)具有如下定義的Action方法ActionMethod提交的標(biāo)單具有如上的輸入元素,在三個(gè)文本框中輸入的字符串將綁定到foo參數(shù),而通過(guò)三個(gè)文件輸入元素上傳得文件將會(huì)綁定給bar參數(shù)。

         1: Public void ActionMethod(string[] foo, HttpPostedFileBase[] bar)

      現(xiàn)在我們對(duì)用于模擬默認(rèn)Model綁定的自定義DefaultModelBinder進(jìn)行進(jìn)一步完善,使之對(duì)基于名稱(chēng)的數(shù)組綁定提供支持。如下面的代碼片斷所示,我們?cè)贐indModel方法中添加了針對(duì)數(shù)組類(lèi)型的Model綁定代碼,而具體的實(shí)現(xiàn)定義在BindArrayModel方法中。

         1: public class DefaultModelBinder
         2: {
         3:     //其他成員    
         4:     public object BindModel(Type parameterType, string prefix)
         5:     {
         6:         if (!this.ValueProvider.ContainsPrefix(prefix))
         7:         {
         8:             return null;
         9:         }
        10:  
        11:         ModelMetadata modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, parameterType);
        12:         if (!modelMetadata.IsComplexType)
        13:         {
        14:             return this.ValueProvider.GetValue(prefix).ConvertTo(parameterType);
        15:         }
        16:         if (parameterType.IsArray)
        17:         {
        18:             return BindArrayModel(parameterType, prefix);
        19:         }
        20:         object model = CreateModel(parameterType);
        21:             
        22:         foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(parameterType))
        23:         {                
        24:             string key = string.IsNullOrEmpty(prefix) ? property.Name : prefix + "." + property.Name;
        25:             property.SetValue(model, BindModel(property.PropertyType, key));
        26:         }
        27:         return model;
        28:     }
        29:     private object BindArrayModel(Type parameterType, string prefix)
        30:     {
        31:         IList list = new List<object>();
        32:         if (this.ValueProvider.ContainsPrefix(prefix))
        33:         {
        34:             IEnumerable enumerable = this.ValueProvider.GetValue(prefix).ConvertTo(parameterType) as IEnumerable;
        35:             if (null != enumerable)
        36:             {
        37:                 foreach (var value in enumerable)
        38:                 {
        39:                     list.Add(value);
        40:                 }
        41:             }
        42:         }           
        43:         Array array = Array.CreateInstance(parameterType.GetElementType(), list.Count);
        44:         list.CopyTo(array,0);
        45:         return array;
        46:     }
        47: }

      定義在BindArrayModel方法中針對(duì)數(shù)組的Model綁定邏輯很簡(jiǎn)單,我們直接通過(guò)ValueProvider將通過(guò)指定前綴得到的數(shù)據(jù)值轉(zhuǎn)換為IEnumerable類(lèi)型,并進(jìn)一步添加到一個(gè)List<object>對(duì)象中,最終我們將該List<object>對(duì)象的元素拷貝到一個(gè)創(chuàng)建的數(shù)組對(duì)象并將其作為Model對(duì)象返回。

      為了演示針對(duì)數(shù)組的Model綁定,我們按照如下的方式修改了Action方法。該方法具有兩個(gè)參數(shù)foo和bar,前者是一個(gè)字符串?dāng)?shù)組,后者的類(lèi)型Bar的Baz屬性是一個(gè)整型數(shù)組。在Action方法中,我們將foo參數(shù)和bar參數(shù)的Baz屬性代表數(shù)組元素呈現(xiàn)出來(lái)。

         1: public class HomeController : Controller
         2: {
         3:     //其他成員
         4:     private IValueProvider GetValueProvider()
         5:     {
         6:         NameValueCollection requestData = new NameValueCollection();
         7:  
         8:         requestData.Add("foo", "abc");
         9:         requestData.Add("foo", "xyz");
        10:  
        11:         requestData.Add("bar.baz", "123");
        12:         requestData.Add("bar.baz", "456");
        13:  
        14:         return new NameValueCollectionValueProvider(requestData, CultureInfo.InvariantCulture);
        15:     }
        16:  
        17:     public void Action(string[] foo, Bar bar)
        18:     {
        19:         Response.Write("foo: <br/>");
        20:         Array.ForEach(foo,item=> Response.Write("&nbsp;&nbsp;&nbsp;&nbsp;"+ item + "<br/>"));
        21:         Response.Write("bar.Baz: <br/>");
        22:         Array.ForEach(bar.Baz, item => Response.Write("&nbsp;&nbsp;&nbsp;&nbsp;" + item + "<br/>"));
        23:     }
        24: }
        25:  
        26: public class Bar
        27: {
        28:     public int[] Baz { get; set; }
        29: }

      通過(guò)GetValueProvider方法提供的NameValueCollectionValueProvider具有針對(duì)這兩個(gè)參數(shù)的數(shù)據(jù)源,從上面的代碼片斷所示,針對(duì)參數(shù)foo和bar的數(shù)據(jù)項(xiàng)具有相同的名稱(chēng)(foo和bar.baz)。該程序運(yùn)行之后會(huì)在瀏覽器中得到如下所示的輸出結(jié)果。

         1: foo: 
         2:     abc
         3:     xyz
         4: bar.Baz: 
         5:     123
         6:     456

      二、基于索引的數(shù)組綁定

      對(duì)于存在于作為ValueProvider數(shù)據(jù)源的NameValueCollection/Dictionary<string, object>中的數(shù)據(jù)項(xiàng)來(lái)說(shuō),如果它們綁定的對(duì)象是一個(gè)數(shù)組,可以采用相同的名稱(chēng)。這樣的Model綁定方式僅僅是用于元素為簡(jiǎn)單類(lèi)型的數(shù)組。除此之外,也可以采用格式為“[index]”的基于索引的前綴來(lái)表示。

      ValueProvider基于索引的匹配策略也可以通過(guò)HtmlHelper<TModel>的模板方法EditorFor來(lái)體現(xiàn)。如下面的代碼片斷所示,在一個(gè)Model類(lèi)型為Contact數(shù)組的強(qiáng)類(lèi)型View中,我們調(diào)用HtmlHelper<TModel>的擴(kuò)展方法EditorFor將數(shù)組的前兩個(gè)元素的相關(guān)信息以編輯模式呈現(xiàn)出來(lái)。

         1: @model Contact[]
         2: @Html.EditorFor(m => m[0].Name)
         3: @Html.EditorFor(m => m[0].PhoneNo)
         4: @Html.EditorFor(m => m[0].EmailAddress)
         5:  
         6: @Html.EditorFor(m => m[1].Name)
         7: @Html.EditorFor(m => m[1].PhoneNo)
         8: @Html.EditorFor(m => m[1].EmailAddress)

      下面的XML片斷代表了上面這段代碼在最終生成的HTML中對(duì)應(yīng)的6個(gè)類(lèi)型為“text”的<input>元素,我們可以清楚地看到它們的名稱(chēng)被添加了[0]和[1]這樣的索引前綴。如果這些元素存在于一個(gè)提交的標(biāo)單中,并且目標(biāo)Action方法包含一個(gè)匹配的Contact數(shù)組類(lèi)型的參數(shù),Model綁定系統(tǒng)將最終生成兩個(gè)元素的Contact數(shù)組作為其參數(shù)值,數(shù)組中元素的順序與索引數(shù)值保持一致。

         1: <input  name="[0].Name" type="text" value="" .../> 
         2: <input  name="[0].PhoneNo" type="text" value="" .../> 
         3: <input  name="[0].EmailAddress" type="text" value="" .../> 
         4:  
         5: <input  name="[1].Name" type="text" value="" .../> 
         6: <input  name="[1].PhoneNo" type="text" value="" .../> 
         7: <input  name="[1].EmailAddress" type="text" value="" .../> 

      基于數(shù)組的Model綁定采用“基零索引”,即將作為數(shù)組下邊界的索引前綴必須是“[0]”。此外,還要求索引在數(shù)值上必須是連續(xù)的。舉個(gè)簡(jiǎn)單的例子,假設(shè)提交的標(biāo)單中具有如下6個(gè)類(lèi)型為“hidden”的<input>元素,它們采用了基于索引的命名,并且從數(shù)字上看索引不是連續(xù)的(缺了一個(gè)[3])。

         1: <input name="[0]" type="hidden" value="foo" />
         2: <input name="[1]" type="hidden" value="bar" />
         3: <input name="[2]" type="hidden" value="baz" />
         4:  
         5: <input name="[4]" type="hidden" value="123" />
         6: <input name="[5]" type="hidden" value="456" />
         7: <input name="[6]" type="hidden" value="789" />   

      如果提供的標(biāo)單對(duì)應(yīng)如下所示的Action方法,上述的<input>元素值將會(huì)綁定到字符串?dāng)?shù)組類(lèi)型的參數(shù)array上。由于索引值不具有連續(xù)性,會(huì)導(dǎo)致后面的三個(gè)<input>元素值(“123”、“456”和“789”)會(huì)被丟棄,也就是說(shuō)綁定后的array參數(shù)值僅僅具有三個(gè)元素(“foo”、“bar”和“baz”)。

         1: public ActionResult Index(string[] array);

      除了采用基零整數(shù)作為數(shù)組索引之外,我們還可以采用任意字符串作為其索引,但是作為索引的字符串需要和數(shù)組元素值一樣存在于ValueProvider的數(shù)據(jù)源中。索引數(shù)據(jù)項(xiàng)名稱(chēng)為“index”,并且與數(shù)組元素?cái)?shù)據(jù)項(xiàng)具有相同的前綴。同樣以上面這個(gè)參數(shù)類(lèi)型為字符串?dāng)?shù)組的Action方法為例,我們可以通過(guò)提交具有如下內(nèi)容的表單來(lái)調(diào)用這個(gè)Action方法并為之提供相應(yīng)的參數(shù)值。

         1: <input name="index" type="hidden" value="first" />
         2: <input name="index" type="hidden" value="second" />
         3: <input name="index" type="hidden" value="third" />
         4:  
         5: <input name="[first]" type="text" value="foo" />
         6: <input name="[second]" type="text" value="bar" />
         7: <input name="[third]" type="text" value="baz" />

      被提交標(biāo)單中三個(gè)類(lèi)型為“text”的<input>元素值將會(huì)綁定到目標(biāo)Action方法的字符串參數(shù)array。它們通過(guò)基于字符串的索引進(jìn)行命名,而作為索引的字符串通過(guò)類(lèi)型為“hidden”的<input>元素和作為參數(shù)綁定的數(shù)據(jù)一并提交。這些用于定義索引字符串的<input>元素一并命名為“index”。

      現(xiàn)在我們對(duì)用于模擬默認(rèn)Model綁定的自定義DefaultModelBinder進(jìn)行進(jìn)一步完善,使之支持基于索引的數(shù)組綁定。如下的代碼片斷所示,我們?cè)谟糜谶M(jìn)行數(shù)組綁定的BindArrayModel方法中添加了額外的代碼用于提取索引值(整型和字符串類(lèi)型)列表,并且根據(jù)這行索引值生成相應(yīng)的前綴和對(duì)應(yīng)的Key通過(guò)ValueProvider得到針對(duì)數(shù)組元素的值。得到的值被添加到預(yù)先創(chuàng)建的對(duì)象列表中并最終成為作為參數(shù)值的數(shù)組對(duì)象的元素。

         1: public class DefaultModelBinder
         2: {
         3:     //其他成員
         4:     public object BindModel(Type parameterType, string prefix)
         5:     {
         6:         if (!this.ValueProvider.ContainsPrefix(prefix))
         7:         {
         8:             return null;
         9:         }
        10:  
        11:         ModelMetadata modelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, parameterType);
        12:         if (!modelMetadata.IsComplexType)
        13:         {
        14:             return this.ValueProvider.GetValue(prefix).ConvertTo(parameterType);
        15:         }
        16:         if (parameterType.IsArray)
        17:         {
        18:             return BindArrayModel(parameterType, prefix);
        19:         }
        20:         object model = CreateModel(parameterType);            
        21:         foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(parameterType))
        22:         {                
        23:             string key = string.IsNullOrEmpty(prefix) ? property.Name : prefix + "." + property.Name;
        24:             property.SetValue(model, BindModel(property.PropertyType, key));
        25:         }
        26:         return model;
        27:     }
        28:  
        29:     private object BindArrayModel(Type parameterType, string prefix)
        30:     {
        31:         List<object> list = new List<object>();
        32:         if (!string.IsNullOrEmpty(prefix) && this.ValueProvider.ContainsPrefix(prefix))
        33:         {
        34:             IEnumerable enumerable = this.ValueProvider.GetValue(prefix).ConvertTo(parameterType) as IEnumerable;
        35:             if (null != enumerable)
        36:             {
        37:                 foreach (var value in enumerable)
        38:                 {
        39:                     list.Add(value);
        40:                 }
        41:             }
        42:         }      
        43:  
        44:         bool numericIndex;
        45:         IEnumerable<string> indexes = GetIndexes(prefix, out numericIndex);
        46:         foreach (var index in indexes)
        47:         {
        48:             string indexPrefix = prefix + "[" + index + "]";
        49:             if (!this.ValueProvider.ContainsPrefix(indexPrefix) && numericIndex)
        50:             {
        51:                 break;
        52:             }
        53:             list.Add(BindModel(parameterType.GetElementType(), indexPrefix));
        54:         }
        55:         object[] array = (object[])Array.CreateInstance(parameterType.GetElementType(), list.Count);
        56:         list.CopyTo(array);
        57:         return array;
        58:     }
        59:     private IEnumerable<string> GetIndexes(string prefix, out bool numericIndex)
        60:     { 
        61:         string key = string.IsNullOrEmpty(prefix)?"index": prefix+"."+"index";
        62:         ValueProviderResult result = this.ValueProvider.GetValue(key);
        63:         if (null != result)
        64:         {
        65:             string[] indexes = result.ConvertTo(typeof(string[])) as string[];
        66:             if (null != indexes)
        67:             {
        68:                 numericIndex = false;
        69:                 return indexes;
        70:             }
        71:         }
        72:         numericIndex = true;
        73:         return GetZeroBasedIndexes();
        74:     }
        75:     private static IEnumerable<string> GetZeroBasedIndexes()
        76:     {
        77:         int iteratorVariable0 = 0;
        78:         while (true)
        79:         {
        80:             yield return iteratorVariable0.ToString();
        81:             iteratorVariable0++;
        82:         }
        83:     }    
        84: }

      索引列表的獲取通過(guò)方法GetIndexes實(shí)現(xiàn)。由于作為索引值的數(shù)據(jù)項(xiàng)以“index”命名,所以該方法在此基礎(chǔ)上加上傳入的前綴作為key調(diào)用ValueProvider的GetValue方法可以直接得到針對(duì)指定前綴的所有字符串類(lèi)型的索引值。而針對(duì)基零整數(shù)的索引列表則通過(guò)GetZeroBasedIndexes方法返回。

      我們現(xiàn)在將自定義的DefaultModelBinder用于進(jìn)行基于數(shù)組的Model綁定,在之前演示實(shí)例的基礎(chǔ)上我們對(duì)Action方法作了如下的修改,使之具有一個(gè)Contact數(shù)組類(lèi)型的參數(shù)。在該Action方法中,我們將作為數(shù)組元素的Contact對(duì)象相關(guān)信息呈現(xiàn)出來(lái)。對(duì)于通過(guò)GetValueProvider方法提供的NameValueCollectionValueProvider來(lái)說(shuō),我們以基零整數(shù)的方式提供了兩個(gè)Contact對(duì)象的數(shù)據(jù)。

         1: public class HomeController : Controller
         2: {    
         3:     //其他成員
         4:     private IValueProvider GetValueProvider()
         5:     {
         6:         NameValueCollection requestData = new NameValueCollection();
         7:  
         8:         requestData.Add("[0].Name", "Foo");
         9:         requestData.Add("[0].PhoneNo", "123456789");
        10:         requestData.Add("[0].EmailAddress", "Foo@gmail.com");
        11:  
        12:         requestData.Add("[1].Name", "Bar");
        13:         requestData.Add("[1].PhoneNo", "987654321");
        14:         requestData.Add("[1].EmailAddress", "Bar@gmail.com");
        15:  
        16:         return new NameValueCollectionValueProvider(requestData, CultureInfo.InvariantCulture);
        17:     }           
        18:  
        19:     public void Action(Contact[] contacts)
        20:     {
        21:         foreach (Contact contact in contacts)
        22:         {
        23:             Response.Write(string.Format("{0}: {1}<br/>", "Name", contact.Name));
        24:             Response.Write(string.Format("{0}: {1}<br/>", "PhoneNo", contact.PhoneNo));
        25:             Response.Write(string.Format("{0}: {1}<br/><br/>", "EmailAddress", contact.EmailAddress));
        26:         }
        27:     }
        28: }

      運(yùn)行我們的程序之后會(huì)在瀏覽器中得到如下所示的輸出結(jié)果,可見(jiàn)目標(biāo)Action的數(shù)組參數(shù)通過(guò)我們自定義的DefaultModelBinder得到了正確地綁定。(S517)

         1: Name: Foo
         2: PhoneNo: 123456789
         3: EmailAddress: Foo@gmail.com
         4:  
         5: Name: Bar
         6: PhoneNo: 987654321
         7: EmailAddress: Bar@gmail.com

      上面這個(gè)例子演示了針對(duì)基零整數(shù)作為索引的數(shù)組綁定,DefaultModelBinder同樣支持針對(duì)任意字符串作為索引的數(shù)組綁定。在下面的代碼片斷中,我們修改了GetValueProvider方法使創(chuàng)建的NameValueCollectionValueProvider以字符串索引的方式為Contact數(shù)組提供數(shù)據(jù)。程序運(yùn)行之后,我們可以在瀏覽器中得到相同的輸出結(jié)果。

         1: public class HomeController : Controller
         2: {
         3:     //其他成員
         4:     private IValueProvider GetValueProvider()
         5:     {
         6:         NameValueCollection requestData = new NameValueCollection();
         7:         requestData.Add("index", "first");
         8:         requestData.Add("index", "second");
         9:  
        10:         requestData.Add("[first].Name", "Foo");
        11:         requestData.Add("[first].PhoneNo", "123456789");
        12:         requestData.Add("[first].EmailAddress", "Foo@gmail.com");
        13:  
        14:         requestData.Add("[second].Name", "Bar");
        15:         requestData.Add("[second].PhoneNo", "987654321");
        16:         requestData.Add("[second].EmailAddress", "Bar@gmail.com");
        17:  
        18:         return new NameValueCollectionValueProvider(requestData, CultureInfo.InvariantCulture);
        19:     }
        20: }

      通過(guò)實(shí)例模擬ASP.NET MVC的Model綁定的機(jī)制:簡(jiǎn)單類(lèi)型+復(fù)雜類(lèi)型
      通過(guò)實(shí)例模擬ASP.NET MVC的Model綁定的機(jī)制:數(shù)組
      通過(guò)實(shí)例模擬ASP.NET MVC的Model綁定的機(jī)制:集合+字典

      posted @ 2012-05-30 08:11  Artech  閱讀(13715)  評(píng)論(9)    收藏  舉報(bào)
      主站蜘蛛池模板: AV秘 无码一区二| 噜噜久久噜噜久久鬼88| 日韩人妻无码一区二区三区99 | 人妻av无码一区二区三区| 国产精品日韩中文字幕熟女| 成人永久免费A∨一级在线播放| 性色在线视频精品| 亚洲国产精品综合久久20| 亚洲精品成人福利网站| 国产自拍在线一区二区三区| 国产日韩精品一区二区三区在线| 久久天天躁狠狠躁夜夜2020老熟妇| 欧美做受视频播放| 国产精品老熟女乱一区二区 | 久久精品国产亚洲AⅤ无码| 欧美日韩免费专区在线观看| 国产美女精品一区二区三区| 国产成人AV一区二区三区在线| 国产婷婷精品av在线| 国产精品不卡区一区二| 亚洲国产中文字幕精品| 一区二区三区午夜福利院| 韩国19禁无遮挡啪啪无码网站| 欧美日韩中文字幕视频不卡一二区| 亚洲AV永久中文无码精品综合| 天堂网av最新版在线看| 国产一区二区三区在线观看免费| 国产福利视频区一区二区| 中文字幕av一区二区三区人妻少妇| 蜜桃av亚洲精品一区二区| 国产区二区三区在线观看| 少妇高潮激情一区二区三| 亚洲国产精品自在拍在线播放蜜臀| 一区二区三区AV波多野结衣| 国产超高清麻豆精品传媒麻豆精品| 人妻少妇偷人精品一区| 最新国产AV最新国产在钱| 少妇人妻偷人精品免费| 久久精品国产亚洲成人av| 国产无套内射又大又猛又粗又爽| 日韩老熟女av搜索结果|