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

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

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

      2025年:是時候重新認識System.Text.Json了

      曾幾何時,在.NET的世界里,Newtonsoft.Json如同一位德高望重的王者,無人不曉。直到有一天,一位名叫System.Text.Json(后文簡稱STJ)的新貴悄然登場。它出身名門(.NET官方),身懷絕技(號稱性能超群),本應是明日之星,卻被無數開發者貼上了“坑王”、“難用”、“反人類”的標簽。

      無數個深夜,開發者們為了解決一個看似簡單的JSON序列化問題,從STJ切換回NSJ,嘴里念叨著:“STJ,勸退了。”然后默默地Install-Package Newtonsoft.Json,仿佛這才是解決問題的唯一“騷操作”。

      但是,這一切真的公平嗎?時過境遷,如今.NET 10的預覽版都已發布,STJ早已不是當年的吳下阿蒙。那些曾經讓你抓狂的“坑”,有多少只是因為誤解了它的設計哲學?有多少早已被新版本填平?

      今天,就讓我們一起為STJ來一場轟轟烈烈的“正名運動”,讓你徹底告別因它而起的“996”!
      image

      告別加班:STJ與Newtonsoft行為對齊實戰

      很多時候,我們覺得STJ“不好用”,僅僅是因為它的默認行為和牛頓不一樣。STJ的設計哲學是:性能優先、安全第一、嚴格遵守RFC 8259規范。而牛頓則更傾向于靈活方便、兼容并包。下面我們就通過一個個小故事和代碼示例,看看如何通過簡單的配置,讓STJ的行為像我們熟悉的老朋友牛頓一樣。

      1. 大小寫問題:前端傳的name,我C#的Name怎么就收不到了?

      背景故事:
      小王剛接手一個前后端分離的項目,前端用JS,遵循駝峰命名(camelCase),傳來一個JSON:{"name": "張三", "age": 18}。后端的C#模型用的是帕斯卡命名(PascalCase):public class User { public string Name { get; set; } public int Age { get; set; } }。結果用STJ一反序列化,user.Nameuser.Age全都是null0!小王抓耳撓腮,查了半天才發現是大小寫匹配問題,差點就要加班調試一晚上了。

      騷操作揭秘:
      STJ為了極致性能,默認是區分大小寫的。而牛頓默認是不區分的。我們只需一個配置項就能解決問題。

      using System.Text.Json;
      
      var jsonFromJs = "{\"name\": \"張三\", \"age\": 18}";
      
      // 默認行為,會匹配失敗
      var optionsDefault = new JsonSerializerOptions();
      var userDefault = JsonSerializer.Deserialize<User>(jsonFromJs, optionsDefault);
      Console.WriteLine($"默認行為: Name = {userDefault.Name}"); // 輸出: 默認行為: Name = 
      
      // 騷操作:開啟不區分大小寫匹配
      var optionsInsensitive = new JsonSerializerOptions
      {
          PropertyNameCaseInsensitive = true
      };
      var userInsensitive = JsonSerializer.Deserialize<User>(jsonFromJs, optionsInsensitive);
      Console.WriteLine($"開啟不區分大小寫: Name = {userInsensitive.Name}"); // 輸出: 開啟不區分大小寫: Name = 張三
      
      public class User
      {
          public string Name { get; set; }
          public int Age { get; set; }
      }
      

      小貼士: 在ASP.NET Core的Web API項目中,默認已經幫你開啟了PropertyNameCaseInsensitive = true,所以你可能根本沒遇到過這個問題,但如果你手動調用JsonSerializer,就需要注意了。

      2. 命名策略:我的UserName怎么就不能變成userName

      背景故事:
      小李的后端API返回的JSON字段都是Pascal風格,比如{"UserName": "Lisi", "IsEnabled": true}。前端小伙伴抱怨說這不符合JS社區的規范,希望能統一用駝峰命名{"userName": "Lisi", "isEnabled": true}。小李心想,難道要把所有C#屬性名都改成小寫開頭?這也太不優雅了!

      騷操作揭秘:
      當然不用!STJ提供了命名策略(Naming Policy),讓你輕松轉換。

      using System.Text.Json;
      
      var user = new User { UserName = "Lisi", IsEnabled = true };
      
      // 默認行為,Pascal風格
      var optionsDefault = new JsonSerializerOptions { WriteIndented = true };
      var jsonDefault = JsonSerializer.Serialize(user, optionsDefault);
      Console.WriteLine("默認輸出:\n" + jsonDefault);
      // 默認輸出:
      // {
      //   "UserName": "Lisi",
      //   "IsEnabled": true
      // }
      
      // 騷操作:指定駝峰命名策略
      var optionsCamelCase = new JsonSerializerOptions
      {
          PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
          WriteIndented = true
      };
      var jsonCamelCase = JsonSerializer.Serialize(user, optionsCamelCase);
      Console.WriteLine("\n駝峰輸出:\n" + jsonCamelCase);
      // 駝峰輸出:
      // {
      //   "userName": "Lisi",
      //   "isEnabled": true
      // }
      
      public class User
      {
          public string UserName { get; set; }
          public bool IsEnabled { get; set; }
      }
      

      小貼士: 同樣,在ASP.NET Core中,默認也幫你配置了駝峰命名策略。這就是為什么你的API天生就符合前端規范。

      3. 注釋和尾隨逗號:這JSON怎么就不“合法”了?

      背景故事:
      老張需要處理一批由其他系統生成的JSON配置文件,這些文件里竟然帶了注釋,而且數組末尾還可能有個多余的逗號,比如 [1, 2, 3, /*這是注釋*/]Newtonsoft.Json處理這些文件毫無壓力,但System.Text.Json一上來就拋出JsonException,直接罷工。

      騷操作揭秘:
      STJ嚴格遵守RFC 8259規范,該規范不允許注釋和尾隨逗號。但為了兼容性,它也提供了開關。

      using System.Text.Json;
      
      // 注意3后面有一個尾隨逗號
      var nonStandardJson = @"{
          ""name"": ""帶注釋的JSON"",
          ""data"": [
              1,
              2,
              3,
          ]
      }";
      
      // 默認行為,直接拋異常
      try
      {
          JsonSerializer.Deserialize<object>(nonStandardJson);
      }
      catch (JsonException ex)
      {
          // The JSON array contains a trailing comma at the end which is not supported in this mode. Change the reader options. Path: $ | LineNumber: 6 | BytePositionInLine: 4.
          Console.WriteLine("默認行為,果然報錯了: " + ex.Message);
      }
      
      // 騷操作:允許注釋和尾隨逗號
      var tolerantOptions = new JsonSerializerOptions
      {
          ReadCommentHandling = JsonCommentHandling.Skip, // 跳過注釋
          AllowTrailingCommas = true // 允許尾隨逗號
      };
      var deserializedObject = JsonSerializer.Deserialize<object>(nonStandardJson, tolerantOptions);
      Console.WriteLine("\n開啟兼容模式后,成功解析!");
      

      4. null值的處理:滿屏的null看著好煩!

      背景故事:
      小趙的API返回的用戶信息里,有些字段是可選的,比如MiddleName。當這些字段沒有值時,序列化出的JSON里會包含"middleName": null。這不僅增加了網絡傳輸的數據量,前端同學也覺得處理起來很麻煩,他們希望null值的字段干脆就不要出現在JSON里。

      騷操作揭秘:
      牛頓通過NullValueHandling.Ignore可以輕松實現,STJ同樣可以。

      using System.Text.Json;
      using System.Text.Json.Serialization;
      
      var user = new User { FirstName = "San", LastName = "Zhang", MiddleName = null };
      
      // 默認行為,包含null值
      var optionsDefault = new JsonSerializerOptions { WriteIndented = true };
      var jsonDefault = JsonSerializer.Serialize(user, optionsDefault);
      Console.WriteLine("默認輸出:\n" + jsonDefault);
      
      // 騷操作:序列化時忽略null值
      var optionsIgnoreNull = new JsonSerializerOptions
      {
          DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
          WriteIndented = true
      };
      var jsonIgnoreNull = JsonSerializer.Serialize(user, optionsIgnoreNull);
      Console.WriteLine("\n忽略null值輸出:\n" + jsonIgnoreNull);
      
      public class User
      {
          public string FirstName { get; set; }
          public string LastName { get; set; }
          public string MiddleName { get; set; }
      }
      

      5. 帶引號的數字:"age": "30" 也能是數字?

      背景故事:
      小孫在對接一個非常“古老”的第三方API,返回的JSON里,所有的數字都是用字符串表示的,例如{"age": "30"}。STJ在反序列化到int Age屬性時直接拋出異常,因為它認為"30"是字符串,不是數字。難道還得先反序列化成string再手動int.Parse

      騷操作揭秘:
      不用那么麻煩,STJ早就想到了這種不規范但常見的情況。

      using System.Text.Json;
      using System.Text.Json.Serialization;
      
      var jsonWithQuotedNumber = @"{""Age"": ""30""}";
      
      // 默認行為,拋出異常
      try
      {
          JsonSerializer.Deserialize<User>(jsonWithQuotedNumber);
      }
      catch (JsonException ex)
      {
          // The JSON value could not be converted to System.Int32. Path: $.Age | LineNumber: 0 | BytePositionInLine: 12.
          Console.WriteLine("默認行為,報錯了: " + ex.Message);
      }
      
      // 騷操作:允許從字符串讀取數字
      var optionsAllowQuotedNumbers = new JsonSerializerOptions
      {
          NumberHandling = JsonNumberHandling.AllowReadingFromString
      };
      var user = JsonSerializer.Deserialize<User>(jsonWithQuotedNumber, optionsAllowQuotedNumbers);
      Console.WriteLine($"\n開啟兼容模式后,Age = {user.Age}");
      
      public class User
      {
          public int Age { get; set; }
      }
      

      6. 循環引用:我和我的老板,誰先序列化?

      背景故事:
      小錢在使用Entity Framework時,遇到了經典難題:Employee對象有個Manager屬性,Manager對象又有個DirectReports列表包含了這個Employee。一序列化,就陷入了“你中有我,我中有你”的無限循環,最終JsonException爆棧。

      騷操作揭秘:
      這是STJ在.NET 5和.NET 6中重點解決的問題。現在我們有兩種選擇。

      using System.Text.Json;
      using System.Text.Json.Serialization;
      
      var manager = new Employee { Name = "老板" };
      var employee = new Employee { Name = "小錢", Manager = manager };
      manager.DirectReports = new List<Employee> { employee };
      
      // 默認行為,拋出循環引用異常
      try
      {
          JsonSerializer.Serialize(employee);
      }
      catch (JsonException ex)
      {
          // A possible object cycle was detected. This can either be due to a cycle or if the object depth is larger than the maximum allowed depth of 64. Consider using ReferenceHandler.Preserve on JsonSerializerOptions to support cycles. 
          // Path: $.Manager.DirectReports.Manager.DirectReports.Manager.DirectReports.……
          Console.WriteLine("默認行為,循環引用報錯: " + ex.Message);
      }
      
      // 騷操作:忽略循環引用點(推薦用于API)
      var optionsIgnoreCycles = new JsonSerializerOptions
      {
          ReferenceHandler = ReferenceHandler.IgnoreCycles,
          WriteIndented = true
      };
      var jsonIgnoreCycles = JsonSerializer.Serialize(employee, optionsIgnoreCycles);
      Console.WriteLine("\n忽略循環引用輸出:\n" + jsonIgnoreCycles);
      // 輸出中,老板的DirectReports里的小錢的Manager屬性會是null
      
      public class Employee
      {
          public string Name { get; set; }
          public Employee Manager { get; set; }
          public List<Employee> DirectReports { get; set; }
      }
      

      小貼士: 還有一個ReferenceHandler.Preserve選項,它會通過$id$ref元數據來完整保留對象圖,適合需要完美往返(round-trip)序列化的場景,但生成的JSON通用性較差。對于Web API,IgnoreCycles通常是更好的選擇。

      7. 枚舉變字符串:別再給我返回01了!

      背景故事:
      小周的API里有個Gender枚舉,序列化后默認變成了數字01。前端每次都要查文檔才知道0Male1Female。這溝通成本也太高了!

      騷操作揭秘:
      一個轉換器就能搞定,讓你的枚舉變得可讀。

      using System.Text.Json;
      using System.Text.Json.Serialization;
      
      var user = new User { Gender = Gender.Male };
      
      // 默認行為,序列化為數字
      var optionsDefault = new JsonSerializerOptions { WriteIndented = true };
      var jsonDefault = JsonSerializer.Serialize(user, optionsDefault);
      Console.WriteLine("默認輸出:\n" + jsonDefault);
      // {
      //   "Gender": 0
      // }
      
      // 騷操作:添加枚舉字符串轉換器
      var optionsEnumAsString = new JsonSerializerOptions
      {
          Converters = { new JsonStringEnumConverter() },
          WriteIndented = true
      };
      var jsonEnumAsString = JsonSerializer.Serialize(user, optionsEnumAsString);
      Console.WriteLine("\n枚舉轉字符串輸出:\n" + jsonEnumAsString);
      // 枚舉轉字符串輸出:
      // {
      //   "Gender": "Male"
      // }
      
      public class User
      {
          public Gender Gender { get; set; }
      }
      
      public enum Gender { Male, Female }
      

      8. 讓JSON回歸人類可讀:與中文和AI友好相處

      背景故事: 我興沖沖地序列化了一個包含中文的對象,準備發給新接入的AI大模型。結果一看日志,"騷操作" 變成了 "\u9A9A\u64CD\u4F5C"!我當時就懵了,這不僅我看著費勁,AI能看懂嗎?Token數暴增暫且不說,理解上出現偏差怎么辦?難道又要退回Newtonsoft?

      騷操作揭秘: 這可能是對STJ誤解最深的一點。STJ默認這樣做,是出于極致的安全考慮。它的默認編碼器JavaScriptEncoder.Default會轉義所有非ASCII字符以及HTML敏感字符(如<, >, &),這是為了防止當你的JSON被不當地嵌入到HTML <script>標簽中時,引發XSS(跨站腳本)攻擊。它遵循的是“默認安全”的最高原則。

      然而,在如今API交互的時代,我們通常通過Content-Type: application/json來通信,數據并不會直接嵌入HTML。特別是在與大模型(LLM)交互時,保持中文字符的原樣不僅能讓我們人類更容易閱讀和調試,更能讓AI準確無誤地理解語義,同時顯著減少Token消耗。這時,我們可以明確地告訴STJ:“我清楚我的使用環境是安全的,請別轉義!”

      // 默認行為:輸出Unicode轉義字符,安全至上
      var escapedJson = JsonSerializer.Serialize("騷操作");
      // escapedJson -> "\u9A9A\u64CD\u4F5C"
      
      // 騷操作配置:在安全的環境下,讓JSON對人類和AI更友好
      var options = new JsonSerializerOptions()
      {
          Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
      };
      var readableJson = JsonSerializer.Serialize("騷操作", options);
      // readableJson -> "騷操作"
      

      你看,STJ不是“坑”,它只是個安全感爆棚、需要你明確指令的“直男”而已。

      9. JsonDocument 難用?你可能找錯了“對標對象”!

      背景故事: 小鄭需要動態地構建一個復雜的JSON對象,或者在反序列化后對JSON結構進行一些增刪改查。他懷念著Newtonsoft.JsonJObjectJArray的靈活與強大,于是他找到了STJ里的JsonDocument。結果他驚奇地發現,這玩意兒居然是只讀的!“這怎么用?連個屬性都不能改,簡直是反人類設計!” 小鄭抱怨道,差點就把STJ拉進了黑名單。

      騷操作揭秘: 這是一個經典的“指鹿為馬”式誤解。JsonDocument的設計目標是對標高性能的只讀文檔模型,它的核心優勢是低內存占用極速查詢,它通過Utf8JsonReader直接操作原始的UTF-8字節流,避免了將整個JSON字符串物化為.NET對象,因此性能極佳。但它的使命是“讀”,而不是“寫”。

      真正的JObject/JArray對標物,是.NET 6中隆重推出的**JsonNode及其派生類JsonObjectJsonArray!這是一個可變的、功能完善的文檔對象模型(DOM)**,它提供了你所期望的一切動態操作能力。

      using System.Text.Json;
      using System.Text.Json.Nodes;
      using System.Text.Encodings.Web;
      
      // 騷操作:使用JsonNode動態構建和修改JSON
      Console.WriteLine("--- 使用JsonNode ---");
      
      // 1. 創建一個JsonObject,就像 new JObject()
      var rootNode = new JsonObject();
      
      // 2. 像字典一樣輕松添加屬性
      rootNode["message"] = "Hello, JsonNode!";
      rootNode["user"] = new JsonObject
      {
          ["name"] = "小鄭",
          ["isActive"] = true
      };
      
      // 3. 添加一個JsonArray
      var scores = new JsonArray(88, 95, 100);
      rootNode["scores"] = scores;
      Console.WriteLine("添加屬性后的JSON:\n" + rootNode.ToJsonString(new JsonSerializerOptions { WriteIndented = true }));
      
      // 4. 輕松修改屬性值
      rootNode["user"]["isActive"] = false;
      Console.WriteLine("\n修改屬性后的JSON:\n" + rootNode.ToJsonString(new JsonSerializerOptions { WriteIndented = true }));
      
      // 5. 序列化為字符串,完美兼容中文
      var finalOptions = new JsonSerializerOptions { WriteIndented = true, Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping };
      var finalJson = rootNode.ToJsonString(finalOptions);
      Console.WriteLine("\n最終輸出(兼容中文):\n" + finalJson);
      

      所以,下次當你想動態操作JSON時,請記住口訣:要讀就用JsonDocument,要寫就用JsonNode

      快速參考:行為對齊配置映射表

      為了方便大家快速查找,我把上面的騷操作整理成了一個表格:

      Newtonsoft.Json 行為 System.Text.Json 默認行為 System.Text.Json 配置 (JsonSerializerOptions) 備注
      反序列化大小寫不敏感 區分大小寫 PropertyNameCaseInsensitive = true ASP.NET Core默認已開啟此選項。
      駝峰命名策略 PascalCase (與C#屬性名一致) PropertyNamingPolicy = JsonNamingPolicy.CamelCase ASP.NET Core默認已開啟此選項。
      忽略JSON注釋 拋出異常 ReadCommentHandling = JsonCommentHandling.Skip
      忽略尾隨逗號 拋出異常 AllowTrailingCommas = true
      序列化時忽略null值 包含null值 DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
      反序列化帶引號的數字 拋出異常 NumberHandling = JsonNumberHandling.AllowReadingFromString 例如,將"123"反序列化為int類型。
      處理循環引用 拋出異常 ReferenceHandler = ReferenceHandler.IgnoreCycles IgnoreCycles將循環點置為null,是API場景的常用選擇。
      枚舉序列化為字符串 序列化為數字 添加 new JsonStringEnumConverter()Converters 集合 Newtonsoft.Json中也有類似的StringEnumConverter
      中文字符轉義 轉義非ASCII字符 Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping 適用于API和AI交互,減少Token消耗。
      動態操作JSON (JObject) JsonDocument (只讀) 使用 JsonNode / JsonObject / JsonArray .NET 6及以后版本可用,功能對標JObject

      STJ的進化之路:從追趕者到引領者

      通過上面的例子,我們看到大部分所謂的“坑”其實都是可以通過JsonSerializerOptions輕松配置的。但我們也要承認,STJ在早期版本中確實存在一些功能上的“天坑”。幸運的是,微軟的開發團隊堪稱“基建狂魔”,他們用一個個版本的迭代,不僅填平了所有坑,更鋪就了一條通往未來的高速公路。

      讓我們沿著時間的脈絡,回顧STJ這場精彩的逆襲之戰:

      .NET 5 - 奠定基礎,補齊核心短板

      這是STJ發布后的第一個“大招版本”,一口氣解決了從Newtonsoft.Json遷移過來的最大痛點,讓STJ在許多真實場景中變得“堪用”。

      • 循環引用處理: 引入ReferenceHandler.Preserve,讓處理EF Core等復雜對象圖不再是噩夢。
      • 非公共成員支持: 帶來了[JsonInclude][JsonConstructor]特性,終于可以序列化私有屬性和使用私有構造函數了,解救了無數依賴封裝性的開發者。
      • 非字符串鍵字典: 開始原生支持Dictionary<int, T>這類常見結構,不再拋出惱人的NotSupportedException

      .NET 6 - 性能飛躍,擁抱現代范式

      如果說.NET 5讓STJ“能用”,那么.NET 6則讓它真正“好用”和“快用”,并為未來的AOT(預編譯)時代打下堅實基礎。

      • 源碼生成器 (JsonSerializerContext): 這是STJ的“核武器”!通過在編譯時生成無反射的序列化代碼,極大地提升了性能、降低了內存占用,并成為Blazor Wasm AOT和Native AOT等場景下的唯一選擇。
      • 可變DOM (JsonNode): 提供了官方的JObject/JArray替代品,讓動態解析和構建復雜的JSON對象變得簡單而類型安全。

      .NET 7 - 功能完備,實現高級定制

      這個版本標志著STJ在功能上基本追平了Newtonsoft.Json,尤其是在高級和復雜的定制場景下,給了開發者充足的信心。

      • 安全的多態序列化: 推出基于[JsonPolymorphic][JsonDerivedType]的白名單式多態支持,功能強大且從設計上根除了Newtonsoft.JsonTypeNameHandling的安全隱患。
      • 終極定制武器 (IJsonTypeInfoResolver): 引入了對標IContractResolver的接口,允許開發者在運行時動態修改類型的序列化“契約”,實現了諸如動態添加/刪除屬性、實現復雜條件序列化等高級“騷操作”。

      .NET 8 - 精益求精,優化開發體驗

      在功能已經非常完善的基礎上,.NET 8更側重于對現有功能的打磨和對開發者體驗的優化。

      • 源碼生成器增強: 完美支持C# 11的requiredinit屬性,讓不可變模型和源碼生成器能更好地協同工作。
      • 內置更多常用類型支持:Half, Int128, UInt128等,并改進了對接口層次結構的支持。

      .NET 9 - 生態集成,引領行業標準

      從.NET 9開始,我們能清晰地看到STJ已經不再滿足于追趕,而是開始作為.NET生態的核心組件,主動引領和定義標準。

      • JSON Schema導出器 (JsonSchemaExporter): 這是一項里程碑式的更新!現在可以直接從你的C#類型生成標準的JSON Schema文檔。這意味著與OpenAPI、Swagger等API工具鏈的集成將變得空前簡單,自動化客戶端生成、API文檔和數據驗證都將因此受益。
      • 更靈活的格式化選項: 允許自定義縮進字符和大小,滿足各種代碼風格和顯示需求。
      • 更強的類型安全: 默認將更嚴格地遵守C#的可空引用類型注解,進一步減少運行時錯誤。

      綜上所述,System.Text.Json的進化之路,是一部清晰的從滿足基本需求,到追求極致性能,再到實現功能完備,并最終引領生態發展的成長史。那些關于它的陳舊“坑論”,早已被滾滾向前的版本車輪碾得粉碎。


      感謝閱讀到這里,如果感覺本文對您有幫助,請不吝評論點贊,這也是我持續創作的動力!

      也歡迎加入我的 .NET騷操作 QQ群:495782587,一起交流.NET 和 AI 的各種有趣玩法!

      posted @ 2025-07-30 08:45  .NET騷操作  閱讀(4780)  評論(42)    收藏  舉報
      主站蜘蛛池模板: 欧美成人免费一区二区三区视频 | 亚洲最大成人av免费看| 日韩精品一二区在线观看| 欧美日韩综合网| 精品国产精品中文字幕| 国产精品小仙女自拍视频| 日韩精品一区二区午夜成人版| 蓝山县| 免费无码高潮流白浆视频| 国产AV影片麻豆精品传媒| 成人午夜免费无码视频在线观看| 老熟妇仑乱换频一区二区| 亚洲国产一区二区三区久| 2019国产精品青青草原| 2019国产精品青青草原| 国产精品成人av在线观看春天| 国产私拍福利精品视频| av在线播放国产一区| 性色av 一区二区三区| 高中女无套中出17p| 国产一区二区亚洲精品| 日韩精品成人一区二区三| 中国猛少妇色xxxxx| 国产一区二区三区精美视频| 东方四虎在线观看av| 上司人妻互换中文字幕| 国产最新AV在线播放不卡| 欧美日韩另类国产| 亚洲国产天堂一区二区三区| 亚洲国产精品久久久天堂麻豆宅男| 精品无码国产污污污免费| 亚洲欧洲日产国码高潮αv| 亚洲精品麻豆一二三区| 日韩精品中文字幕一线不卡| 99噜噜噜在线播放| 亚洲av二区三区在线| 在线免费不卡视频| 无码综合天天久久综合网 | 国产成人无码AV片在线观看不卡| 日韩三级一区二区在线看| 成人无套少萝内射中出|