一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - C# WebApi 接口傳參詳解

C# WebApi 接口傳參詳解

2022-02-25 14:17懶得安分 C#

這篇文章主要介紹了C# WebApi 接口傳參詳解,本篇打算通過get、post、put、delete四種請求方式分別談談基礎類型(包括int/string/datetime等)、實體、數組等類型的參數如何傳遞。感興趣的小伙伴們可以參考一下

前言:還記得剛使用webapi那會兒,被它的傳參機制折騰了好久,查閱了半天資料。如今,使用webapi也有段時間了,今天就記錄下api接口傳參的一些方式方法,算是一個筆記,也希望能幫初學者少走彎路。本篇針對初初使用webapi的同學們,比較基礎,有興趣的且看看。

本篇打算通過get、post、put、delete四種請求方式分別談談基礎類型(包括int/string/datetime等)、實體、數組等類型的參數如何傳遞。

一、get請求

對于取數據,我們使用最多的應該就是get請求了吧。下面通過幾個示例看看我們的get請求參數傳遞。

1、基礎類型參數

?
1
2
3
4
5
[httpget]
public string getallchargingdata(int id, string name)
{
  return "chargingdata" + id;
}
?
1
2
3
4
5
6
7
8
9
10
$.ajax({
    type: "get",
    url: "http://localhost:27221/api/charging/getallchargingdata",
    data: { id: 1, name: "jim", bir: "1988-09-11"},
    success: function (data, status) {
      if (status == "success") {
        $("#div_test").html(data);
      }
    }
  });

參數截圖效果

C# WebApi 接口傳參詳解

這是get請求最基礎的參數傳遞方式,沒什么特別好說的。

2、實體作為參數

如果我們在get請求時想將實體對象做參數直接傳遞到后臺,是否可行呢?我們來看看。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class tb_charging
  {
    /// <summary>
    /// 主鍵id
    /// </summary>
    public string id { get; set; }
 
    /// <summary>
    /// 充電設備名稱
    /// </summary>
    public string name { get; set; }
 
    /// <summary>
    /// 充電設備描述
    /// </summary>
    public string des { get; set; }
 
    /// <summary>
    /// 創建時間
    /// </summary>
    public datetime createtime { get; set; }
  }
?
1
2
3
4
5
[httpget]
public string getbymodel(tb_charging odata)
{
   return "chargingdata" + odata.id;
}
?
1
2
3
4
5
6
7
8
9
10
11
$.ajax({
    type: "get",
    url: "http://localhost:27221/api/charging/getbymodel",
    contenttype: "application/json",
    data: { id: "1", name: "jim", createtime: "1988-09-11" },
    success: function (data, status) {
      if (status == "success") {
        $("#div_test").html(data);
      }
    }
  });

測試結果

C# WebApi 接口傳參詳解

由上圖可知,在get請求時,我們直接將json對象當做實體傳遞后臺,后臺是接收不到的。這是為什么呢?我們來看看對應的http請求

C# WebApi 接口傳參詳解

原來,get請求的時候,默認是將參數全部放到了url里面直接以string的形式傳遞的,后臺自然接不到了。

原因分析:還記得有面試題問過get和post請求的區別嗎?其中有一個區別就是get請求的數據會附在url之后(就是把數據放置在http協議頭中),而post請求則是放在http協議包的包體中。

根據園友們的提議,get請求的時候可以在參數里面加上[fromuri]即可直接得到對象。還是貼上代碼:

?
1
2
3
4
5
6
7
var postdata = { id: "1", name: "jim", createtime: "1988-09-11" };
  $.ajax({
    type: "get",
    url: "http://localhost:27221/api/charging/getallchargingdata",
    data: postdata,
    success: function (data, status) { }
  });
?
1
2
3
4
5
[httpget]
public string getallchargingdata([fromuri]tb_charging obj)
{
  return "chargingdata" + obj.id;
}

得到結果:

C# WebApi 接口傳參詳解

如果你不想使用[fromuri]這些在參數里面加特性的這種“怪異”寫法,也可以采用先序列化,再在后臺反序列的方式。

?
1
2
3
4
5
6
7
8
9
10
11
$.ajax({
    type: "get",
    url: "http://localhost:27221/api/charging/getbymodel",
    contenttype: "application/json",
    data: { strquery: json.stringify({ id: "1", name: "jim", createtime: "1988-09-11" }) },
    success: function (data, status) {
      if (status == "success") {
        $("#div_test").html(data);
      }
    }
  });
?
1
2
3
4
5
6
[httpget]
    public string getbymodel(string strquery)
    {
      tb_charging odata = newtonsoft.json.jsonconvert.deserializeobject<tb_charging>(strquery);
      return "chargingdata" + odata.id;
    }

C# WebApi 接口傳參詳解

這樣在后臺得到我們序列化過的對象,再通過反序列化就能得到對象。

在url里面我們可以看到它自動給對象加了一個編碼:

C# WebApi 接口傳參詳解

至于還有園友們提到的model binder這種方式,博主看了下,覺得略復雜。有興趣的也可以試試。至于用哪一種方式傳遞對象,園友們可以自行選擇。

3、數組作為參數

一般get請求不建議將數組作為參數,因為我們知道get請求傳遞參數的大小是有限制的,最大1024字節,數組里面內容較多時,將其作為參數傳遞可能會發生參數超限丟失的情況。

4、“怪異”的get請求

為什么會說get請求“怪異”呢?我們先來看看下面的兩種寫法對比。

(1)webapi的方法名稱以get開頭

?
1
2
3
4
5
6
7
8
9
10
11
$.ajax({
    type: "get",
    url: "http://localhost:27221/api/charging/getbymodel",
    contenttype: "application/json",
    data: { strquery: json.stringify({ id: "1", name: "jim", createtime: "1988-09-11" }) },
    success: function (data, status) {
      if (status == "success") {
        $("#div_test").html(data);
      }
    }
  });
?
1
2
3
4
5
6
[httpget]
    public string getbymodel(string strquery)
    {
      tb_charging odata = newtonsoft.json.jsonconvert.deserializeobject<tb_charging>(strquery);
      return "chargingdata" + odata.id;
    }

這是標準寫法,后臺加[httpget],參數正常得到:

C# WebApi 接口傳參詳解

為了對比,我將[httpget]去掉,然后再調用

?
1
2
3
4
5
6
//[httpget]
    public string getbymodel(string strquery)
    {
      tb_charging odata = newtonsoft.json.jsonconvert.deserializeobject<tb_charging>(strquery);
      return "chargingdata" + odata.id;
    }

C# WebApi 接口傳參詳解

貌似沒有任何問題!有人就想,那是否所有的get請求都可以省略掉[httpget]這個標注呢。我們試試便知。

(2)webapi的方法名稱不以get開頭

我們把之前的方法名由getbymodel改成findbymodel,這個再正常不過了,很多人查詢就不想用get開頭,還有直接用query開頭的。這個有什么關系嗎?有沒有關系,我們以事實說話。

?
1
2
3
4
5
6
7
8
9
10
11
$.ajax({
    type: "get",
    url: "http://localhost:27221/api/charging/findbymodel",
    contenttype: "application/json",
    data: { strquery: json.stringify({ id: "1", name: "jim", createtime: "1988-09-11" }) },
    success: function (data, status) {
      if (status == "success") {
        $("#div_test").html(data);
      }
    }
  });
?
1
2
3
4
5
6
[httpget]
    public string findbymodel(string strquery)
    {
      tb_charging odata = newtonsoft.json.jsonconvert.deserializeobject<tb_charging>(strquery);
      return "chargingdata" + odata.id;
    }

C# WebApi 接口傳參詳解

貌似又可行,沒有任何問題啊。根據上面的推論,我們去掉[httpget]也是可行的,好,我們注釋掉[httpget],運行起來試試。

C# WebApi 接口傳參詳解

結果是不進斷點,有些人不信,我們在瀏覽器里面看看http請求:

C# WebApi 接口傳參詳解

呵呵,這就奇怪了,就改了個方法名,至于這樣么?還真至于!

博主的理解是:方法名以get開頭,webapi會自動默認這個請求就是get請求,而如果你以其他名稱開頭而又不標注方法的請求方式,那么這個時候服務器雖然找到了這個方法,但是由于請求方式不確定,所以直接返回給你405——方法不被允許的錯誤。

最后結論:所有的webapi方法最好是加上請求的方式([httpget]/[httppost]/[httpput]/[httpdelete]),不要偷懶,這樣既能防止類似的錯誤,也有利于方法的維護,別人一看就知道這個方法是什么請求。

這也就是為什么很多人在園子里面問道為什么方法名不加[httpget]就調用不到的原因!

二、post請求

在webapi的resetful風格里面,api服務的增刪改查,分別對應著http的post/delete/put/get請求。我們下面就來說說post請求參數的傳遞方式。

1、基礎類型參數

post請求的基礎類型的參數和get請求有點不一樣,我們知道get請求的參數是通過url來傳遞的,而post請求則是通過http的請求體中傳過來的,webapi的post請求也需要從http的請求體里面去取參數。

(1)錯誤的寫法

?
1
2
3
4
5
6
7
8
9
10
$.ajax({
    type: "post",
    url: "http://localhost:27221/api/charging/savedata",
    data: { name: "jim" },
    success: function (data, status) {
      if (status == "success") {
        $("#div_test").html(data);
      }
    }
  });
?
1
2
3
4
5
[httppost]
public bool savedata(string name)
{
  return true;
}

這是一種看上去非常正確的寫法,可是實際情況是:

C# WebApi 接口傳參詳解

(2)正確的用法

?
1
2
3
4
5
6
$.ajax({
    type: "post",
    url: "http://localhost:27221/api/charging/savedata",
    data: { "": "jim" },
    success: function (data, status) {}
  });
?
1
2
3
4
5
[httppost]
   public bool savedata([frombody]string name)
   {
     return true;
   }

這是一種另許多人頭痛的寫法,但是沒辦法,這樣確實能得到我們的結果:

C# WebApi 接口傳參詳解

我們一般的通過url取參數的機制是鍵值對,即某一個key等于某一個value,而這里的frombody和我們一般通過url取參數的機制則不同,它的機制是=value,沒有key的概念,并且如果你寫了key(比如你的ajax參數寫的{name:"jim"}),后臺反而得到的name等于null。不信你可以試試。

上面講的都是傳遞一個基礎類型參數的情況,那么如果我們需要傳遞多個基礎類型呢?按照上面的推論,是否可以([frombody]string name, [frombody]string des)這樣寫呢。試試便知。

(1)錯誤寫法

?
1
2
3
4
5
6
$.ajax({
    type: "post",
    url: "http://localhost:27221/api/charging/savedata",
    data: { "": "jim","":"備注" },
    success: function (data, status) {}
  });
?
1
2
3
4
5
[httppost]
   public bool savedata([frombody]string name, [frombody] string des)
   {
     return true;
   }

得到結果

C# WebApi 接口傳參詳解

C# WebApi 接口傳參詳解

這說明我們沒辦法通過多個[frombody]里面取值,此法失敗。

(2)正確用法

既然上面的辦法行不通,那我們如何傳遞多個基礎類型的數據呢?很多的解決辦法是新建一個類去包含傳遞的參數,博主覺得這樣不夠靈活,因為如果我們前后臺每次傳遞多個參數的post請求都去新建一個類的話,我們系統到時候會有多少個這種參數類?維護起來那是相當的麻煩的一件事!所以博主覺得使用dynamic是一個很不錯的選擇。我們來試試。

?
1
2
3
4
5
6
7
$.ajax({
    type: "post",
    url: "http://localhost:27221/api/charging/savedata",
    contenttype: 'application/json',
    data: json.stringify({ name: "jim",des:"備注" }),
    success: function (data, status) {}
  });
?
1
2
3
4
5
6
[httppost]
    public object savedata(dynamic obj)
    {
      var strname = convert.tostring(obj.name);
      return strname;
    }

C# WebApi 接口傳參詳解

通過dynamic動態類型能順利得到多個參數,省掉了[frombody]這個累贅,并且ajax參數的傳遞不用使用"無厘頭"的{"":"value"}這種寫法,有沒有一種小清新的感覺~~有一點需要注意的是這里在ajax的請求里面需要加上參數類型為json,即contenttype: 'application/json',這個屬性。

(3)推薦用法

通過上文post請求基礎類型參數的傳遞,我們了解到了dynamic的方便之處,為了避免[frombody]這個累贅和{"":"value"}這種"無厘頭"的寫法。博主推薦所有基礎類型使用dynamic來傳遞,方便解決了基礎類型一個或多個參數的傳遞,示例如上文。如果園友們有更好的辦法,歡迎討論。

2、實體作為參數

(1)單個實體作為參數

上面我們通過dynamic類型解決了post請求基礎類型數據的傳遞問題,那么當我們需要傳遞一個實體作為參數該怎么解決呢?我們來看下面的代碼便知:

?
1
2
3
4
5
6
$.ajax({
    type: "post",
    url: "http://localhost:27221/api/charging/savedata",
    data: { id: "1", name: "jim", createtime: "1988-09-11" },
    success: function (data, status) {}
  });
?
1
2
3
4
5
[httppost]
    public bool savedata(tb_charging odata)
    {
      return true;
    }

得到結果

C# WebApi 接口傳參詳解

原理解釋:使用實體作為參數的時候,前端直接傳遞普通json,后臺直接使用對應的類型去接收即可,不用frombody。但是這里需要注意的一點就是,這里不能指定contenttype為appplication/json,否則,參數無法傳遞到后臺。我們來看看它默認的contenttype是什么:

C# WebApi 接口傳參詳解

為了弄清楚原因,博主查了下http的content-type的類型。看到如下說明:

  • application/x-www-form-urlencoded : <form enctype=””>中默認的enctype,form表單數據被編碼為key/value格式發送到服務器(表單默認的提交數據的格式);
  • application/json : json數據格式

也就是說post請求默認是將表單里面的數據的key/value形式發送到服務,而我們的服務器只需要有對應的key/value屬性值的對象就可以接收到。而如果使用application/json,則表示將前端的數據以序列化過的json傳遞到后端,后端要把它變成實體對象,還需要一個反序列化的過程。按照這個邏輯,那我們如果指定contenttype為application/json,然后傳遞序列化過的對象應該也是可以的啊。博主好奇心重,還是打算一試到底,于是就有了下面的代碼:

?
1
2
3
4
5
6
7
8
var postdata = { id: "1", name: "jim", createtime: "1988-09-11" };
  $.ajax({
    type: "post",
    url: "http://localhost:27221/api/charging/savedata",
    contenttype: 'application/json',
    data: json.stringify(postdata),
    success: function (data, status) {}
  });
?
1
2
3
4
5
[httppost]
   public bool savedata(tb_charging lstcharging)
   {
     return true;
   }

得到結果:

C# WebApi 接口傳參詳解

嘗試成功,也就是說,兩種寫法都是可行的。如果你指定了contenttype為application/json,則必須要傳遞序列化過的對象;如果使用post請求的默認參數類型,則前端直接傳遞json類型的對象即可。

(2)實體和基礎類型一起作為參數傳遞

有些時候,我們需要將基礎類型和實體一起傳遞到后臺,這個時候,我們神奇的dynamic又派上用場了。

?
1
2
3
4
5
6
7
8
var postdata = { id: "1", name: "jim", createtime: "1988-09-11" };
  $.ajax({
    type: "post",
    url: "http://localhost:27221/api/charging/savedata",
    contenttype: 'application/json',
    data: json.stringify({ name:"lilei", charging:postdata }),
    success: function (data, status) {}
  });
?
1
2
3
4
5
6
7
[httppost]
    public object savedata(dynamic obj)
    {
      var strname = convert.tostring(obj.name);
      var ocharging = newtonsoft.json.jsonconvert.deserializeobject<tb_charging>(convert.tostring(obj.charging));
      return strname;
    }

得到結果:

C# WebApi 接口傳參詳解

原理也不用多說,同上。

3、數組作為參數

(1)基礎類型數組

?
1
2
3
4
5
6
7
8
var arr = ["1", "2", "3", "4"];
  $.ajax({
    type: "post",
    url: "http://localhost:27221/api/charging/savedata",
    contenttype: 'application/json',
    data: json.stringify(arr),
    success: function (data, status) { }
  });
?
1
2
3
4
5
[httppost]
   public bool savedata(string[] ids)
   {
     return true;
   }

得到結果:

C# WebApi 接口傳參詳解

(2)實體集合

?
1
2
3
4
5
6
7
8
9
10
11
12
var arr = [
    { id: "1", name: "jim", createtime: "1988-09-11" },
    { id: "2", name: "lilei", createtime: "1990-12-11" },
    { id: "3", name: "lucy", createtime: "1986-01-10" }
  ];
  $.ajax({
    type: "post",
    url: "http://localhost:27221/api/charging/savedata",
    contenttype: 'application/json',
    data: json.stringify(arr),
    success: function (data, status) {}
  });
?
1
2
3
4
5
[httppost]
    public bool savedata(list<tb_charging> lstcharging)
    {
      return true;
    }

得到結果:

C# WebApi 接口傳參詳解

4、后臺發送請求參數的傳遞

上面寫了那么多,都是通過前端的ajax請求去做的,我們知道,如果調用方不是web項目,比如android客戶端,可能需要從后臺發送http請求來調用我們的接口方法,如果我們通過后臺去發送請求是否也是可行的呢?我們以實體對象作為參數來傳遞寫寫代碼試一把。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public void testreques()
    {
       //請求路徑
      string url = "http://localhost:27221/api/charging/savedata";
 
      //定義request并設置request的路徑
      webrequest request = webrequest.create(url);
      request.method = "post";
 
      //初始化request參數
      string postdata = "{ id: \"1\", name: \"jim\", createtime: \"1988-09-11\" }";
 
      //設置參數的編碼格式,解決中文亂碼
      byte[] bytearray = encoding.utf8.getbytes(postdata);
 
      //設置request的mime類型及內容長度
      request.contenttype = "application/json";
      request.contentlength = bytearray.length;
 
      //打開request字符流
      stream datastream = request.getrequeststream();
      datastream.write(bytearray, 0, bytearray.length);
      datastream.close();
 
      //定義response為前面的request響應
      webresponse response = request.getresponse();
 
      //獲取相應的狀態代碼
      console.writeline(((httpwebresponse)response).statusdescription);
 
      //定義response字符流
      datastream = response.getresponsestream();
      streamreader reader = new streamreader(datastream);
      string responsefromserver = reader.readtoend();//讀取所有
      console.writeline(responsefromserver);
    }

當代碼運行到request.getresponse()這一句的時候,api里面進入斷點

C# WebApi 接口傳參詳解

嘗試成功。

三、put請求

webapi里面put請求一般用于對象的更新。它和用法和post請求基本相同。同樣支持[frombody],同樣可以使用dynamic。

1、基礎類型參數

?
1
2
3
4
5
6
7
$.ajax({
    type: "put",
    url: "http://localhost:27221/api/charging/update",
    contenttype: 'application/json',
    data: json.stringify({ id: "1" }),
    success: function (data, status) {}
  });
?
1
2
3
4
5
[httpput]
   public bool update(dynamic obj )
   {
     return true;
   }

C# WebApi 接口傳參詳解

2、實體作為參數

和post請求相同。

3、數組作為參數

和post請求相同。

四、delete請求

顧名思義,delete請求肯定是用于刪除操作的。參數傳遞機制和post也是基本相同。下面簡單給出一個例子,其他情況參考post請求。

?
1
2
3
4
5
6
7
8
9
10
11
12
var arr = [
    { id: "1", name: "jim", createtime: "1988-09-11" },
    { id: "2", name: "lilei", createtime: "1990-12-11" },
    { id: "3", name: "lucy", createtime: "1986-01-10" }
  ];
  $.ajax({
    type: "delete",
    url: "http://localhost:27221/api/charging/optdelete",
    contenttype: 'application/json',
    data: json.stringify(arr),
    success: function (data, status) {}
  });
?
1
2
3
4
5
[httpdelete]
   public bool optdelete(list<tb_charging> lstchargin)
   {
     return true;
   }

C# WebApi 接口傳參詳解

五、總結

以上比較詳細的總結了webapi各種請求的各種參數傳遞。每種情況都是博主實際代碼測試過的,內容不難,但如果剛接觸這么些東西還是需要一點時間去熟悉的,在此做個總結,希望能幫到剛剛接觸webapi的園友們。如果本文能幫到你,不妨推薦下,您的推薦是博主繼續總結的動力!

原文鏈接:http://www.cnblogs.com/landeanfen/p/5337072.html

延伸 · 閱讀

精彩推薦
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
主站蜘蛛池模板: 免费人成黄页在线观看69 | 小浪妇奶真大水多 | 免费永久观看美女视频网站网址 | 日韩亚洲国产激情在线观看 | 亚洲精品福利一区二区在线观看 | 韩国三级日本三级香港三级黄 | 精品综合一区二区三区 | 二次元美女扒开内裤露尿口 | 日本三级s级在线播放 | 色哟约 | 韩国伦理hd| 激情影院网站 | 亚洲网红精品大秀在线观看 | 日本视频在线免费观看 | 精品国产一级在线观看 | 国产视频中文字幕 | 日本孕妇大胆孕交 | 我们日本在线观看免费动漫下载 | 精品久久亚洲 | 99久久精品国产一区二区 | 强女明星系列小说 | 色在线看 | 动漫白丝袜美女羞羞 | 亚洲情射 | 色老板美国在线观看 | 免费一级特黄特色大片在线 | 免费99精品国产自在现线 | 成人小视频在线观看 | 国产精品久久久久久网站 | 国产女主播福利在线 | 亚洲码和乱人伦中文一区 | 国精品午夜dy8888狼人 | 日韩成人在线网站 | 美女岳肉太深了使劲 | 高清麻生希在线 | gay男男白袜chinese | 天堂va在线| 91大片淫黄大片在线天堂 | 欧美性色欧美a在线播放 | 美女被扣逼 | 草莓秋葵菠萝蜜绿巨人污 |