簡體   English   中英

如何在POST請求上將json.net用於asp.net核心模型綁定?

[英]How to use json.net for asp.net core model binding on POST requests?

我看到了另一個問題 ,沒有答案。

我需要使用newtonsoft反序列化,因為在將數據發送到客戶端時,我有循環引用循環處理:

services.AddMvc()
.AddJsonOptions(options =>
                    {
                        options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                        options.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
                        options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
                        options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                    });

這將生成帶有$id$ref JSON對象,這些對象使模型綁定程序在修改后的數據返回時對POST請求失敗。

請注意,我有一個非常復雜的對象模型,如下所示:

{
  "$id": "1",
  "vehiculeId": 359586015016459,
  "companyId": 1,
  "phoneNumber": "0614407055",
  "hardwareId": 866857042994208,
  "gpsBoxType": 29,
  "name": "Redmi Note 6 Pro Olivier M",
  "iconId": 33554432,
  "gpsBoxTrackingDelay": 1,
  "rowEnabled": true,
  "dbInsertTime": 1549527854940,
  "device": {
    "$id": "2",
    "imei": 866857042994208,
    "brand": "Xiaomi",
    "model": "Redmi Note 6 Pro",
    "name": "Redmi Olivier",
    "registration": {
      "$id": "3",
      "imei": 866857042994208,
      "companyId": 1,
      "latestRegistrationStatusChangeDate": 1556168520000,
      "registrationStatus": 3,
      "imeiNavigation": {
        "$ref": "2"
      }
    }
  },
  "vehiculeGpsBoxInfo": {
    "$id": "4",
    "vehiculeId": 359586015016459,
    "currentDelay": 0,
    "normalTrackingMode": 2,
    "timeModeDelay": 60000,
    "smartModeDelay": 5000,
    "smartModeDistance": 100,
    "connected": false,
    "heartBeatPeriod": 1200,
    "insureCoherence": false,
    "killHedgehog": true,
    "lastCommunicationTime": 1563519489853,
    "vehiculeConfiguration": 111,
    "updateStatus": 0,
    "vehicule": {
      "$ref": "1"
    },
    "vehiculeConfigurationNavigation": {
      "$id": "5",
      "configurationId": 111,
      "configName": "PTIMobileTest",
      "masterName": "PTIMobileTest",
      "master": "1.0.32",
      "firmware": "",
      "system": "",
      "gpsBoxType": 29,
      "vehiculeGpsBoxInfoBoardConfigurationNavigation": [],
      "vehiculeGpsBoxInfoVehiculeConfigurationNavigation": [
        {
          "$ref": "4"
        }
      ]
    }
  },
  "fleetDetail": [
    {
      "$id": "6",
      "fleetDetailId": 27494,
      "fleetId": 3216,
      "vehiculeId": 359586015016459,
      "rowEnabled": true,
      "fleet": {
        "$id": "7",
        "fleetId": 3216,
        "companyId": 1,
        "name": "RTEProtect",
        "rowEnabled": true,
        "fleetDetailFleet": [
          {
            "$id": "8",
            "fleetDetailId": 25988,
            "fleetId": 3216,
            "vehiculeId": 359586014995819,
            "rowEnabled": true,
            "fleet": {
              "$ref": "7"
            },
            "vehicule": {
              "$id": "9",
              "vehiculeId": 359586014995819,
              "companyId": 1,
              "phoneNumber": " ",
              "hardwareId": 358240051111110,
              "gpsBoxType": 29,
              "category": "PTI",
              "name": "PTI Emulateur Fred",
              "iconId": 33571442,
              "gpsBoxTrackingDelay": 1,
              "addressProtocol": 0,
              "rowEnabled": true,
              "dbInsertTime": 1448607218600,
              "device": {
                "$id": "10",
                "imei": 358240051111110,
                "brand": "Unknown",
                "model": "PTI Emulateur",
                "name": "PTI Emulateur Fred",
                "registration": {
                  "$id": "11",
                  "imei": 358240051111110,
                  "companyId": 1,
                  "latestRegistrationStatusChangeDate": 1556169720000,
                  "registrationStatus": 3,
                  "imeiNavigation": {
                    "$ref": "10"
                  }
                }
              },
              "vehiculeGpsBoxInfo": {
                "$id": "12",
                "vehiculeId": 359586014995819,
                "currentDelay": 0,
                "normalTrackingMode": 2,
                "timeModeDelay": 60000,
                "smartModeDelay": 5000,
                "smartModeDistance": 100,
                "connected": false,
                "heartBeatPeriod": 1200,
                "insureCoherence": false,
                "killHedgehog": true,
                "boardConnected": false,
                "lastCommunicationTime": 1558078487030,
                "boardLastCommunicationTime": 1485957716897,
                "vehiculeConfiguration": 169,
                "updateStatus": 0,
                "vehicule": {
                  "$ref": "9"
                },
                "vehiculeConfigurationNavigation": {
                  "$id": "13",
                  "configurationId": 169,
                  "configName": "SafeProtectSamsungS6",
                  "masterName": "SafeProtectSamsungS6",
                  "master": "1.0.2",
                  "firmware": "",
                  "system": "",
                  "gpsBoxType": 29,
                  "vehiculeGpsBoxInfoBoardConfigurationNavigation": [],
                  "vehiculeGpsBoxInfoVehiculeConfigurationNavigation": [
                    {
                      "$ref": "12"
                    },
                    {
                      "$id": "14",
                      "vehiculeId": 359586015014836,
                      "currentDelay": 0,
                      "normalTrackingMode": 2,
                      "timeModeDelay": 60000,
                      "smartModeDelay": 5000,
                      "smartModeDistance": 100,
                      "connected": true,
                      "heartBeatPeriod": 1200,
                      "insureCoherence": false,
                      "killHedgehog": true,
                      "lastCommunicationTime": 1568202416063,
                      "vehiculeConfiguration": 169,
                      "updateStatus": 0,
                      "lastConnexionTime": 1545057192063,
                      "vehicule": {
                        "$id": "15",
                        "vehiculeId": 359586015014836,
                        "companyId": 1,
                        "phoneNumber": "+351927853883",
                        "hardwareId": 356437083709729,
                        "gpsBoxType": 29,
                        "name": "Samsung J5 test",
                        "iconId": 33569462,
                        "gpsBoxTrackingDelay": 1,
                        "addressProtocol": 0,
                        "rowEnabled": true,
                        "dbInsertTime": 1513945397863,
                        "device": {
                          "$id": "16",
                          "imei": 356437083709729,
                          "brand": "Samsung",
                          "model": "J5",
                          "name": "Test"
                        },
                        "vehiculeGpsBoxInfo": {
                          "$ref": "14"
                        },
                        "fleetDetail": [
                          {
                            "$id": "17",
                            "fleetDetailId": 26445,
                            "fleetId": 3486,
                            "vehiculeId": 359586015014836,
                            "rowEnabled": true,
                            "fleet": {
                              "$id": "18",
                              "fleetId": 3486,
                              "companyId": 1,
                              "name": "RTE Protect",
                              "rowEnabled": true,
                              "fleetDetailFleet": [
                                {
                                  "$id": "19",
                                  "fleetDetailId": 13251,
                                  "fleetId": 3486,
                                  "vehiculeId": 359586014995819,
                                  "rowEnabled": true,
                                  "fleet": {
                                    "$ref": "18"
                                  },
                                  "vehicule": {
                                    "$ref": "9"
                                  }
                                },
                                {
                                  "$id": "20",
                                  "fleetDetailId": 13477,
                                  "fleetId": 3486,
                                  "vehiculeId": 359586014995819,
                                  "rowEnabled": false,
                                  "fleet": {
                                    "$ref": "18"
                                  },
                                  "vehicule": {
                                    "$ref": "9"
                                  }
                                },
                                {
                                  "$ref": "17"
                                }
                              ],
                              "fleetDetailFleetChildNavigation": []
                            },
                            "vehicule": {
                              "$ref": "15"
                            }
                          },
                          {
                            "$id": "21",
                            "fleetDetailId": 27485,
                            "fleetId": 5536,
                            "vehiculeId": 359586015014836,
                            "rowEnabled": true,
                            "fleet": {
                              "$id": "22",
                              "fleetId": 5536,
                              "companyId": 1,
                              "name": "SafeProtect",
                              "rowEnabled": true,
                              "fleetDetailFleet": [
                                {
                                  "$ref": "21"
                                }
                              ],
                              "fleetDetailFleetChildNavigation": []
                            },
                            "vehicule": {
                              "$ref": "15"
                            }
                          }
                        ]
                      },
                      "vehiculeConfigurationNavigation": {
                        "$ref": "13"
                      }
                    },
                    {
                      "$id": "23",
                      "vehiculeId": 359586015014947,
                      "currentDelay": 0,
                      "normalTrackingMode": 2,
                      "timeModeDelay": 60000,
                      "smartModeDelay": 5000,
                      "smartModeDistance": 100,
                      "connected": false,
                      "heartBeatPeriod": 1200,
                      "insureCoherence": false,
                      "killHedgehog": true,
                      "lastCommunicationTime": 1558006034977,
                      "vehiculeConfiguration": 169,
                      "updateStatus": 0,
                      "vehicule": {
                        "$id": "24",
                        "vehiculeId": 359586015014947,
                        "companyId": 1,
                        "phoneNumber": " ",
                        "hardwareId": 357011072523992,
                        "gpsBoxType": 29,
                        "name": "SafeProtect Céline Pro",
                        "iconId": 33554432,
                        "gpsBoxTrackingDelay": 1,
                        "addressProtocol": 0,
                        "rowEnabled": true,
                        "dbInsertTime": 1538134175170,
                        "device": {
                          "$id": "25",
                          "imei": 357011072523992,
                          "brand": "Samsung",
                          "model": "S6",
                          "name": "S6 Céline",
                          "registration": {
                            "$id": "26",
                            "imei": 357011072523992,
                            "companyId": 1,
                            "latestRegistrationStatusChangeDate": 1556103600000,
                            "registrationStatus": 3,
                            "imeiNavigation": {
                              "$ref": "25"
                            }
                          }
                        },
                        "vehiculeGpsBoxInfo": {
                          "$ref": "23"
                        },
                        "fleetDetail": []
                      },
                      "vehiculeConfigurationNavigation": {
                        "$ref": "13"
                      }
                    }
                  ]
                }
              },
              "fleetDetail": [
                {
                  "$id": "27",
                  "fleetDetailId": 26334,
                  "fleetId": 659,
                  "vehiculeId": 359586014995819,
                  "rowEnabled": false,
                  "fleet": {
                    "$id": "28",
                    "fleetId": 659,
                    "companyId": 1,
                    "name": "Parc",
                    "rowEnabled": true,
                    "fleetDetailFleet": [
                      {
                        "$ref": "27"
                      }
                    ],
                    "fleetDetailFleetChildNavigation": []
                  },
                  "vehicule": {
                    "$ref": "9"
                  }
                },
                {
                  "$ref": "8"
                },
                {
                  "$id": "29",
                  "fleetDetailId": 25993,
                  "fleetId": 3216,
                  "vehiculeId": 359586014995819,
                  "rowEnabled": false,
                  "fleet": {
                    "$ref": "7"
                  },
                  "vehicule": {
                    "$ref": "9"
                  }
                },
                {
                  "$ref": "19"
                },
                {
                  "$ref": "20"
                }
              ]
            }
          },
          {
            "$ref": "29"
          },
          {
            "$ref": "6"
          }
        ],
        "fleetDetailFleetChildNavigation": []
      },
      "vehicule": {
        "$ref": "1"
      }
    },
    {
      "$id": "30",
      "fleetDetailId": 27476,
      "fleetId": 5534,
      "vehiculeId": 359586015016459,
      "rowEnabled": true,
      "fleet": {
        "$id": "31",
        "fleetId": 5534,
        "companyId": 1,
        "name": "Ol",
        "rowEnabled": true,
        "fleetDetailFleet": [
          {
            "$ref": "30"
          }
        ],
        "fleetDetailFleetChildNavigation": []
      },
      "vehicule": {
        "$ref": "1"
      }
    }
  ]
}

目前,我的控制器方法如下:

   [HttpPost]
    public async Task<IActionResult> UpdateDati([FromBody] Vehicule model)
    {...}

令我驚訝的是,沒有簡單的方法可以區分這種行為以進行模型綁定。 我在這里想念什么?

解決方案是編寫一個自定義模型綁定程序,以使用JSON.Net反序列化請求主體:

/// <summary>
    /// Custom model binder to be used when TrackableEntities coming in HttpPost Methods.
    /// </summary>
    public class TrackableEntityModelBinder : IModelBinder
    {
        /// <inheritdoc/>
        public async Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
            {
                throw new ArgumentNullException(nameof(bindingContext));
            }

            using (var reader = new StreamReader(bindingContext.HttpContext.Request.Body))
            {
                var body = await reader.ReadToEndAsync().ConfigureAwait(continueOnCapturedContext: false);

                // Do something
                var value = JsonConvert.DeserializeObject(body, bindingContext.ModelType, new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    ContractResolver = new CamelCasePropertyNamesContractResolver(),
                    ReferenceLoopHandling = ReferenceLoopHandling.Serialize,
                    PreserveReferencesHandling = PreserveReferencesHandling.Objects,
                });

                bindingContext.Result = ModelBindingResult.Success(value);
            }
        }
    }

然后,只需注釋HttpPost方法參數即可使用模型綁定器:

[HttpPost]
public async Task<IActionResult> UpdateDati([ModelBinder(typeof(TrackableEntityModelBinder))] [FromBody] Vehicule model)
{
}

您可以嘗試刪除它們嗎:

.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;

您的Vehicule對象是否匹配(我剛剛在VS中使用特殊粘貼)

public class Rootobject
{
    public string id { get; set; }
    public long vehiculeId { get; set; }
    public int companyId { get; set; }
    public string phoneNumber { get; set; }
    public long hardwareId { get; set; }
    public int gpsBoxType { get; set; }
    public string name { get; set; }
    public int iconId { get; set; }
    public int gpsBoxTrackingDelay { get; set; }
    public bool rowEnabled { get; set; }
    public long dbInsertTime { get; set; }
    public Device device { get; set; }
    public Vehiculegpsboxinfo vehiculeGpsBoxInfo { get; set; }
    public Fleetdetail[] fleetDetail { get; set; }
}

public class Device
{
    public string id { get; set; }
    public long imei { get; set; }
    public string brand { get; set; }
    public string model { get; set; }
    public string name { get; set; }
    public Registration registration { get; set; }
}

public class Registration
{
    public string id { get; set; }
    public long imei { get; set; }
    public int companyId { get; set; }
    public long latestRegistrationStatusChangeDate { get; set; }
    public int registrationStatus { get; set; }
    public Imeinavigation imeiNavigation { get; set; }
}

public class Imeinavigation
{
    public string _ref { get; set; }
}

public class Vehiculegpsboxinfo
{
    public string id { get; set; }
    public long vehiculeId { get; set; }
    public int currentDelay { get; set; }
    public int normalTrackingMode { get; set; }
    public int timeModeDelay { get; set; }
    public int smartModeDelay { get; set; }
    public int smartModeDistance { get; set; }
    public bool connected { get; set; }
    public int heartBeatPeriod { get; set; }
    public bool insureCoherence { get; set; }
    public bool killHedgehog { get; set; }
    public long lastCommunicationTime { get; set; }
    public int vehiculeConfiguration { get; set; }
    public int updateStatus { get; set; }
    public Vehicule vehicule { get; set; }
    public Vehiculeconfigurationnavigation vehiculeConfigurationNavigation { get; set; }
}

public class Vehicule
{
    public string _ref { get; set; }
}

public class Vehiculeconfigurationnavigation
{
    public string id { get; set; }
    public int configurationId { get; set; }
    public string configName { get; set; }
    public string masterName { get; set; }
    public string master { get; set; }
    public string firmware { get; set; }
    public string system { get; set; }
    public int gpsBoxType { get; set; }
    public object[] vehiculeGpsBoxInfoBoardConfigurationNavigation { get; set; }
    public Vehiculegpsboxinfovehiculeconfigurationnavigation[] vehiculeGpsBoxInfoVehiculeConfigurationNavigation { get; set; }
}

public class Vehiculegpsboxinfovehiculeconfigurationnavigation
{
    public string _ref { get; set; }
}

public class Fleetdetail
{
    public string id { get; set; }
    public int fleetDetailId { get; set; }
    public int fleetId { get; set; }
    public long vehiculeId { get; set; }
    public bool rowEnabled { get; set; }
    public Fleet fleet { get; set; }
    public Vehicule7 vehicule { get; set; }
}

public class Fleet
{
    public string id { get; set; }
    public int fleetId { get; set; }
    public int companyId { get; set; }
    public string name { get; set; }
    public bool rowEnabled { get; set; }
    public Fleetdetailfleet[] fleetDetailFleet { get; set; }
    public object[] fleetDetailFleetChildNavigation { get; set; }
}

public class Fleetdetailfleet
{
    public string id { get; set; }
    public int fleetDetailId { get; set; }
    public int fleetId { get; set; }
    public long vehiculeId { get; set; }
    public bool rowEnabled { get; set; }
    public Fleet1 fleet { get; set; }
    public Vehicule1 vehicule { get; set; }
    public string _ref { get; set; }
}

public class Fleet1
{
    public string _ref { get; set; }
}

public class Vehicule1
{
    public string id { get; set; }
    public long vehiculeId { get; set; }
    public int companyId { get; set; }
    public string phoneNumber { get; set; }
    public long hardwareId { get; set; }
    public int gpsBoxType { get; set; }
    public string category { get; set; }
    public string name { get; set; }
    public int iconId { get; set; }
    public int gpsBoxTrackingDelay { get; set; }
    public int addressProtocol { get; set; }
    public bool rowEnabled { get; set; }
    public long dbInsertTime { get; set; }
    public Device1 device { get; set; }
    public Vehiculegpsboxinfo1 vehiculeGpsBoxInfo { get; set; }
    public Fleetdetail2[] fleetDetail { get; set; }
}

public class Device1
{
    public string id { get; set; }
    public long imei { get; set; }
    public string brand { get; set; }
    public string model { get; set; }
    public string name { get; set; }
    public Registration1 registration { get; set; }
}

public class Registration1
{
    public string id { get; set; }
    public long imei { get; set; }
    public int companyId { get; set; }
    public long latestRegistrationStatusChangeDate { get; set; }
    public int registrationStatus { get; set; }
    public Imeinavigation1 imeiNavigation { get; set; }
}

public class Imeinavigation1
{
    public string _ref { get; set; }
}

public class Vehiculegpsboxinfo1
{
    public string id { get; set; }
    public long vehiculeId { get; set; }
    public int currentDelay { get; set; }
    public int normalTrackingMode { get; set; }
    public int timeModeDelay { get; set; }
    public int smartModeDelay { get; set; }
    public int smartModeDistance { get; set; }
    public bool connected { get; set; }
    public int heartBeatPeriod { get; set; }
    public bool insureCoherence { get; set; }
    public bool killHedgehog { get; set; }
    public bool boardConnected { get; set; }
    public long lastCommunicationTime { get; set; }
    public long boardLastCommunicationTime { get; set; }
    public int vehiculeConfiguration { get; set; }
    public int updateStatus { get; set; }
    public Vehicule2 vehicule { get; set; }
    public Vehiculeconfigurationnavigation1 vehiculeConfigurationNavigation { get; set; }
}

public class Vehicule2
{
    public string _ref { get; set; }
}

public class Vehiculeconfigurationnavigation1
{
    public string id { get; set; }
    public int configurationId { get; set; }
    public string configName { get; set; }
    public string masterName { get; set; }
    public string master { get; set; }
    public string firmware { get; set; }
    public string system { get; set; }
    public int gpsBoxType { get; set; }
    public object[] vehiculeGpsBoxInfoBoardConfigurationNavigation { get; set; }
    public Vehiculegpsboxinfovehiculeconfigurationnavigation1[] vehiculeGpsBoxInfoVehiculeConfigurationNavigation { get; set; }
}

public class Vehiculegpsboxinfovehiculeconfigurationnavigation1
{
    public string _ref { get; set; }
    public string id { get; set; }
    public long vehiculeId { get; set; }
    public int currentDelay { get; set; }
    public int normalTrackingMode { get; set; }
    public int timeModeDelay { get; set; }
    public int smartModeDelay { get; set; }
    public int smartModeDistance { get; set; }
    public bool connected { get; set; }
    public int heartBeatPeriod { get; set; }
    public bool insureCoherence { get; set; }
    public bool killHedgehog { get; set; }
    public long lastCommunicationTime { get; set; }
    public int vehiculeConfiguration { get; set; }
    public int updateStatus { get; set; }
    public long lastConnexionTime { get; set; }
    public Vehicule3 vehicule { get; set; }
    public Vehiculeconfigurationnavigation2 vehiculeConfigurationNavigation { get; set; }
}

public class Vehicule3
{
    public string id { get; set; }
    public long vehiculeId { get; set; }
    public int companyId { get; set; }
    public string phoneNumber { get; set; }
    public long hardwareId { get; set; }
    public int gpsBoxType { get; set; }
    public string name { get; set; }
    public int iconId { get; set; }
    public int gpsBoxTrackingDelay { get; set; }
    public int addressProtocol { get; set; }
    public bool rowEnabled { get; set; }
    public long dbInsertTime { get; set; }
    public Device2 device { get; set; }
    public Vehiculegpsboxinfo2 vehiculeGpsBoxInfo { get; set; }
    public Fleetdetail1[] fleetDetail { get; set; }
}

public class Device2
{
    public string id { get; set; }
    public long imei { get; set; }
    public string brand { get; set; }
    public string model { get; set; }
    public string name { get; set; }
    public Registration2 registration { get; set; }
}

public class Registration2
{
    public string id { get; set; }
    public long imei { get; set; }
    public int companyId { get; set; }
    public long latestRegistrationStatusChangeDate { get; set; }
    public int registrationStatus { get; set; }
    public Imeinavigation2 imeiNavigation { get; set; }
}

public class Imeinavigation2
{
    public string _ref { get; set; }
}

public class Vehiculegpsboxinfo2
{
    public string _ref { get; set; }
}

public class Fleetdetail1
{
    public string id { get; set; }
    public int fleetDetailId { get; set; }
    public int fleetId { get; set; }
    public long vehiculeId { get; set; }
    public bool rowEnabled { get; set; }
    public Fleet2 fleet { get; set; }
    public Vehicule5 vehicule { get; set; }
}

public class Fleet2
{
    public string id { get; set; }
    public int fleetId { get; set; }
    public int companyId { get; set; }
    public string name { get; set; }
    public bool rowEnabled { get; set; }
    public Fleetdetailfleet1[] fleetDetailFleet { get; set; }
    public object[] fleetDetailFleetChildNavigation { get; set; }
}

public class Fleetdetailfleet1
{
    public string id { get; set; }
    public int fleetDetailId { get; set; }
    public int fleetId { get; set; }
    public long vehiculeId { get; set; }
    public bool rowEnabled { get; set; }
    public Fleet3 fleet { get; set; }
    public Vehicule4 vehicule { get; set; }
    public string _ref { get; set; }
}

public class Fleet3
{
    public string _ref { get; set; }
}

public class Vehicule4
{
    public string _ref { get; set; }
}

public class Vehicule5
{
    public string _ref { get; set; }
}

public class Vehiculeconfigurationnavigation2
{
    public string _ref { get; set; }
}

public class Fleetdetail2
{
    public string id { get; set; }
    public int fleetDetailId { get; set; }
    public int fleetId { get; set; }
    public long vehiculeId { get; set; }
    public bool rowEnabled { get; set; }
    public Fleet4 fleet { get; set; }
    public Vehicule6 vehicule { get; set; }
    public string _ref { get; set; }
}

public class Fleet4
{
    public string id { get; set; }
    public int fleetId { get; set; }
    public int companyId { get; set; }
    public string name { get; set; }
    public bool rowEnabled { get; set; }
    public Fleetdetailfleet2[] fleetDetailFleet { get; set; }
    public object[] fleetDetailFleetChildNavigation { get; set; }
    public string _ref { get; set; }
}

public class Fleetdetailfleet2
{
    public string _ref { get; set; }
}

public class Vehicule6
{
    public string _ref { get; set; }
}

public class Vehicule7
{
    public string _ref { get; set; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM