来自包含双精度数字的 Json 帖子的错误 400(错误请求)
Posted
技术标签:
【中文标题】来自包含双精度数字的 Json 帖子的错误 400(错误请求)【英文标题】:Error 400 (Bad Request) from Json post containing double-precision numbers 【发布时间】:2020-09-26 12:48:27 【问题描述】:我正在向将结果数据存储在数据库中的服务器发送常规帖子。很多时候,服务器返回 400 错误,这似乎意味着帖子格式错误。但是我可以告诉(从正确的数据存储在数据库中的事实)有时服务器已经接受了数据。 Json 非常简单,每次都几乎相同,例如
"latitude":50.2905,"longitude":5.04548,"recorded_at":"20200925 21:07:31","owner":1。
有时它会毫无错误地被接受。如果数据通过 WiFi/宽带或通过 4G 发送,则会发生错误。 发送数据的(Xamarin)代码如下:
private string UploadResult(WebClient client, double lat, double lng, DateTime t)
client.Headers[HttpRequestHeader.ContentType] = "application/json";
lat = Math.Round(lat, 5);
lng = Math.Round(lng, 5);
json = string.Format("\"latitude\":0,\"longitude\":1,\"recorded_at\":\"2\",\"owner\":3",
lat, lng, DBTime(t), MyLocation.owner);
Uri uri = new Uri(UrlBase.urlBase + "SaveLocation");
string result = client.UploadString(uri, json);
return result;
我无权访问服务器来调试它,只能查看数据库条目。这是一个将数据存储在 MSSQL 数据库中的 WCF 服务,经纬度以十进制 (10,6) 形式存储。我相当确定问题是最近才出现的,即使相关代码没有更改 - 我之前没有收到这些错误(无论如何都不明显)。
我在这里做了很多搜索并尝试了很多代码更改,所有这些都没有效果。我在使用不同版本的 Visual Stuio、Xamarin 和 android API 级别时遇到了同样的问题。
最终我尝试在发布之前降低经纬度的精度,即
lat = Math.Round(lat, 1);
lng = Math.Round(lng, 1);
和 Bingo!,一切都很好(当然除了我的数据库的准确性)。有 2 位或更多小数位会导致错误返回。
很明显,可以将服务器代码更改为仅接受整数,并以不同的方式发送数据,但这会很棘手。我可以在客户端代码中更改什么来解决这个问题?
[稍后] 我尝试为十进制数字添加正确的字符串格式
json = string.Format("\"latitude\":0:0.0000,\"longitude\":1:0.0000,\"recorded_at\":\"2\",\"owner\":3", ....
但这并没有什么不同。有趣的是,我还尝试将数字作为字符串发送
json = string.Format("\"latitude\":\"0\",\"longitude\":\"1\",\"recorded_at\":\"2\",\"owner\":3", ......
这同样被接受,但错误频率相同。据我了解,数字数据应该作为字符串被拒绝。
【问题讨论】:
【参考方案1】:通过将 WebClient 更改为 HttpClient 来解决它。我知道 WebClient 是老技术,但我很早以前就编写了原始代码,它确实可以正常工作。
private async Task<HttpResponseMessage> UploadResult(double lat, double lng, DateTime t)
lat = Math.Round(lat, 5);
lng = Math.Round(lng, 5);
using (HttpClient httpClient = new HttpClient())
string json = string.Format("\"latitude\":0:0.00000,\"longitude\":1:0.00000,\"recorded_at\":\"2\",\"owner\":3",
lat, lng, DBTime(t), Location.owner);
var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json");
HttpResponseMessage response = null;
Uri uri = new Uri(UrlBase.urlBase + "SaveLocation");
try
response = await httpClient.PostAsync(uri, content);
catch (Exception ex)
if (response == null)
response = new HttpResponseMessage();
response.StatusCode = HttpStatusCode.InternalServerError;
response.ReasonPhrase = string.Format("Post failed: 0", ex.Message);
return response;
也需要用await调用这个函数。
【讨论】:
感谢分享。不要忘记接受答案。以上是关于来自包含双精度数字的 Json 帖子的错误 400(错误请求)的主要内容,如果未能解决你的问题,请参考以下文章
Json.NET 用最少的小数位序列化浮点/双精度,即没有多余的“.0”?
如何避免以科学记数法表示的双精度数和数字的字符串到数字转换?