對於400錯誤,出現的原因大概有幾個。
一:第一步確認postmen中發送的數據類型是json。比如Headers中Content-Type類型是application/json;或是前端代碼Ajax中添加:contentType: 'application/json;charset=UTF-8';
二:確認postmen中發送的數據格式是否正確。postmen中經常有人有漏寫一對“{}“或是缺少逗號,引號,冒號的小問,好在postmen會自動報錯提示; 而在前端中你必須重新包裝傳入參數為JSON型。使用JSON.stringify(params)將params參數重新包裝;
三:檢查參數的類型是否一一對應;
四:對接接口時,有可能參數的值不匹配,比如說地址不符合實際要求時,可能返回400錯誤提示;
本人遇到的屬於第四種情況,在檢查完預報參數類型和數據格式之后,依然報400錯誤,后來發現是對方地址有驗證,有實際的報錯信息,但是我們得到的是400錯誤,怎么解決呢?
下面貼代碼:
1.預報參數

//創建貨件,設置請求參數
public ShipmentRequest SetRequest(Package package, PBUSPSConfig Config) { var model = new ShipmentRequest(); string[] address1 = new string[] { package.SenderAddress.Address };//發件地址
string[] address2 = new string[] { !string.IsNullOrWhiteSpace(package.ShippingAddress.Address)? package.ShippingAddress.Address:"", !string.IsNullOrWhiteSpace(package.ShippingAddress.Address2)? package.ShippingAddress.Address2:"" , !string.IsNullOrWhiteSpace(package.ShippingAddress.Address3) ? package.ShippingAddress.Address3:"" };//收件地址
foreach (var packageInfo in package.PackageInfos) { //1磅等於453.59克
double weights = Convert.ToDouble(packageInfo.Weight * 1000); //常衡盎司:重量單位。整體縮寫為oz.av。 1盎司 = 28.350克
decimal Weight = Convert.ToDecimal(weights / 28.350);//重量轉盎司
model.fromAddress = new Address() { company = package.SenderAddress.CompanyName, name = package.SenderAddress.FirstName, phone = !string.IsNullOrWhiteSpace(package.SenderAddress.PhoneNumber) ? package.SenderAddress.PhoneNumber : package.SenderAddress.Mobile, email = package.SenderAddress.Email, residential = false, addressLines = address1, cityTown = package.SenderAddress.City, stateProvince = package.SenderAddress.Province, postalCode = package.SenderAddress.PostalCode, countryCode = package.SenderAddress.CountryCode, }; model.toAddress = new Address() { company = package.ShippingAddress.CompanyName, name = package.ShippingAddress.FirstName, phone =!string.IsNullOrWhiteSpace(package.ShippingAddress.PhoneNumber)? package.ShippingAddress.PhoneNumber: package.ShippingAddress.Mobile, email = "", residential = false, addressLines = address2, cityTown = package.ShippingAddress.City, stateProvince = !string.IsNullOrWhiteSpace(localityProvincia) ? localityProvincia : package.ShippingAddress.Province, postalCode = package.ShippingAddress.PostalCode, countryCode = package.ShippingAddress.CountryCode, }; model.parcel = new parcel() { weight = new Weight() { unitOfMeasurement = "OZ",//度量單位
weight = Weight,//包裹的重量
}, dimension = new Dimension() { unitOfMeasurement = "IN", length=10, width=4, height=6, irregularParcelGirth = "20"//將此設置為不規則包裹的周長。周長是高度和寬度之和的兩倍:
} }; model.rates = new rates[] { new rates() { carrier="NEWGISTICS", serviceId="PRCLSEL", parcelType="PKG", specialServices= new SpecialServices[]{ new SpecialServices() { specialServiceId="DelCon" }, new SpecialServices() { specialServiceId="NOTIFICATIONS", inputParameters=new InputParameters[] { new InputParameters(){ name="RECIPIENT_NOTIFICATION_TYPE", value="ON_DELIVER" }, new InputParameters(){ name="RECIPIENT_NOTIFICATION_EMAIL", value="widgets@example.com" } } } } } }; model.documents = new documents[] { new documents(){ type="SHIPPING_LABEL", contentType="URL", size="DOC_4X6", fileFormat="PDF", } }; model.shipmentOptions = new shipmentOptions[] { new shipmentOptions(){ name="SHIPPER_ID", value=Config.ShipperId, }, new shipmentOptions(){ name="IS_RECTANGULAR", value="false", }, new shipmentOptions(){ name="CLIENT_FACILITY_ID", value=Config.ClientFacilityId, }, new shipmentOptions(){ name="CARRIER_FACILITY_ID", value=Config.CarrierFacilityId, }, new shipmentOptions(){ name="NON_DELIVERY_OPTION", //大於一磅的包裹,就是這樣的值ChangeServiceRequested, 小於一磅的,就空着,不填
value=weights > 453.59?"ChangeServiceRequested":"", } }; } return model; }
2.訪問接口返回值

1 //創建貨件,取返回參數 ShipmentResponse 2 public string GetResponse(ShipmentRequest ShipmentRequest, string access_token, PBUSPSConfig config) 3 { 4 var stopWatch = new Stopwatch(); 5 var Url = config.ForecastUrl + "/shippingservices/v1/shipments?includeDeliveryCommitment=true"; 6 var TransactionId = GenerateStringID(); 7 HttpWebRequest request = null; 8 if (Url.StartsWith("https", StringComparison.OrdinalIgnoreCase)) 9 { 10 request = WebRequest.Create(Url) as HttpWebRequest; 11 request.ProtocolVersion = HttpVersion.Version11; 12 request.KeepAlive = false; 13 } 14 else 15 { 16 request = (HttpWebRequest)WebRequest.Create(Url); 17 } 18 request.Method = "POST"; 19 request.ContentType = "application/json"; 20 request.Accept = "application/json"; 21 request.AllowAutoRedirect = true; 22 request.Headers.Add("Authorization", "Bearer " + access_token); 23 request.Headers.Add("X-PB-TransactionId", TransactionId); 24 Stream myRequestStream = request.GetRequestStream(); 25 StreamWriter myStreamWriter = 26 new StreamWriter(myRequestStream, Encoding.GetEncoding("utf-8")); 27 var Ship = JsonConvert.SerializeObject(ShipmentRequest); 28 byte[] data = Encoding.UTF8.GetBytes(Ship); 29 SetCertificatePolicy(); 30 using (Stream requestStream = request.GetRequestStream()) 31 { 32 requestStream.Write(data, 0, data.Length); 33 } 34 using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 35 { 36 Stream myResponseStream = response.GetResponseStream(); 37 StreamWriter myStreamReader = 38 new StreamWriter(myResponseStream, Encoding.GetEncoding("utf-8")); 39 using (StreamReader reader = new StreamReader(response.GetResponseStream())) 40 { 41 return reader.ReadToEnd(); 42 } 43 } 44 }
3.處理400錯誤

View Code
4.在得到具體的返回值之后,發現返回值是一個以中括號開頭和結尾的字符串類型,添加一個實體類,映射返回值

1 public class Errors { 2 [JsonProperty("errorCode")] 3 public string errorCode { get; set; } 4 [JsonProperty("message")] 5 public string message { get; set; } 6 [JsonProperty("parameters")] 7 public string[] parameters { get; set; } 8 }
以上就是處理400參數的解決方案。
5.取Token

1 //獲取Token 2 public static string GetToken(PBUSPSConfig Config, Encoding encoding) 3 { 4 if (encoding == null) 5 encoding = Encoding.UTF8; 6 //根據Key獲取緩存中的Auth值 7 var cacheKey = "PBUSPSREQUESTTOKEN"; 8 var cacheResult = Cache.Get<string>(cacheKey); 9 10 if (!string.IsNullOrWhiteSpace(cacheResult)) 11 return cacheResult; 12 13 var stopWatch = new Stopwatch(); 14 var Key = Config.Key;//鍵 15 var Secret = Config.Secret;//值 16 var Token = ForecastHelper.Base64(Key, Secret); 17 var Url = Config.ForecastUrl + "/oauth/token"; 18 string paramStr = "grant_type=client_credentials"; 19 20 WebClient wc = new WebClient(); 21 // 采取POST方式必須加的Header 22 wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); 23 wc.Headers.Add("Authorization", "Basic " + Token); 24 byte[] postData = encoding.GetBytes(paramStr); 25 SetCertificatePolicy(); 26 byte[] responseData = wc.UploadData(Url, "POST", postData); // 得到返回字符流 27 string result = encoding.GetString(responseData);// 解碼 28 if (result != null) 29 { 30 if (result.Contains("error")) 31 { 32 var OAuthError = SerializeUtil.FromJson<Error>(result); 33 return "服務商:" + OAuthError.errors[0].errorDescription; 34 } 35 else 36 { 37 var OAuthresult = SerializeUtil.FromJson<TokenResponse>(result); 38 var access_token = OAuthresult.access_token;//取Auth值 39 Cache.Add(cacheKey, access_token, 480); // 添加進緩存 有效時間8個小時 40 return access_token; 41 } 42 } 43 return "CMS:服務商返回為空"; 44 }
6.“基礎連接已經關閉”的錯誤

1 private static void SetCertificatePolicy() 2 { 3 ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); 4 // 這里設置了協議類型。 5 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Ssl3;// SecurityProtocolType.Tls1.2; 6 ServicePointManager.CheckCertificateRevocationList = true; 7 ServicePointManager.DefaultConnectionLimit = 100; 8 ServicePointManager.Expect100Continue = false; 9 } 10 private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) 11 { 12 return true; //總是接受 13 }