NewtonSoft JsonConvert.SerializeObject 确实将零序列化为负零(0 序列化为 -0.0)
NewtonSoft JsonConvert.SerializeObject does serialize zero to negative zero ( 0 serialized like as -0.0 )
我有一个 ASP.NET 5 Web API
项目。我使用 MsSql 2016
数据库。我从数据库中获取数据并通过 API return 将其发送到应用程序。但我有一个问题。 API returns 0
喜欢 -0.0
(负零)
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(ConfigManager.ConnectionString));
services.AddControllersWithViews().AddNewtonsoftJson();
services.AddSwaggerGen(c =>
{
c.OperationFilter<AddXUserIdRequiredHeaderParameter>();
//c.OperationFilter<AddXLanguageHeaderParameter>();
c.SwaggerDoc("v1", new OpenApiInfo { Title = "MyManagerWS", Version = "v1" });
// Set the comments path for the swagger json and ui.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
}
public class DbHelper {
public static GetDataOutput GetData(int userId, GetDataInput input)
{
var result = new ReportItemStockDataResponse();
string sqlQuery = @"SELECT ItemId,
ItemName,
ItemCode,
Barcode,
ActualAmount,
UnitName,
RealAmount,
SpecialAmount,
ActualAmountWithSecondUnit,
RealAmountWithSecondUnit,
SpecialAmountWithSecondUnit,
SecondUnitName,
FROM
MyTable";
try
{
using (var connDb = new SqlConnection(_connectionString))
{
connDb.Open();
using (var command = connDb.CreateCommand())
{
using (var dr = command.ExecuteReader())
{
while (dr.Read())
{
result.ItemStockLines.Add(
new ReportItemStockDataResponse.ItemStock()
{
ItemId = Convert.ToInt32(dr["ItemId"]),
ItemName = dr["ItemName"].ToString(),
ItemCode = dr["ItemCode"].ToString(),
Barcode = dr["Barcode"].ToString(),
ActualAmount = Convert.ToDouble(dr["ActualAmount"]),
UnitName = dr["UnitName"].ToString(),
RealAmount = Convert.ToDouble(dr["RealAmount"]),
SpecialAmount = Convert.ToDouble(dr["SpecialAmount"]),
ActualAmountWithSecondUnit = Convert.ToDouble(dr["ActualAmountWithSecondUnit"]),
RealAmountWithSecondUnit = Convert.ToDouble(dr["RealAmountWithSecondUnit"]),
SpecialAmountWithSecondUnit = Convert.ToDouble(dr["SpecialAmountWithSecondUnit"]),
SecondUnitName = dr["SecondUnitName"].ToString(),
});
}
}
}
}
}
catch (Exception ex)
{
_logger.Error(ex, "Error");
result = null;
}
return result;
}
}
var result=DbHelper.GetData();
var serializedResult = JsonConvert.SerializeObject(result);
序列化结果如下:
{
"itemStockLines": [
{
"itemId": 111222333,
"itemCode": "Test code",
"itemName": "Test item",
"barcode": "",
"actualAmount": -0.0,
"realAmount": -0.0,
"specialAmount": -0.0,
"unitName": "ADET",
"secondUnitName": "QUTU",
"actualAmountWithSecondUnit": -0.0,
"realAmountWithSecondUnit": -0.0,
"specialAmountWithSecondUnit": -0.0
}
]
}
但 actualAmount
、realAmount
、specialAmount
、actualAmountWithSecondUnit
、realAmountWithSecondUnit
、specialAmountWithSecondUnit
在 C# 和 DB 中为零。
注意: 这些是 C# 中的双变量
Microsoft.AspNetCore.Mvc.NewtonsoftJson版本为5.0.3
感谢您的帮助
我不期待任何赞成票或反对票。仅供参考。
谁想了解更多关于符号零的信息我可以推荐
和 https://en.wikipedia.org/wiki/Signed_zero
我做了这个测试只是为了记录。对我来说,结果看起来很有趣。我反序列化了 PO json 并使用 NewtonsoftJson 再次对其进行了序列化。所有负零双打仍然是负数
var jsonDeserealized=JsonConvert.DeserializeObject<Root>(json);
var jsonReversed=JsonConvert.SerializeObject(jsonDeserealized);
结果
{
"itemStockLines": [
{
"itemId": 111222333,
"itemCode": "Test code",
"itemName": "Test item",
"barcode": "",
"actualAmount": -0.0,
"realAmount": -0.0,
"specialAmount": -0.0,
"unitName": "ADET",
"secondUnitName": "QUTU",
"actualAmountWithSecondUnit": -0.0,
"realAmountWithSecondUnit": -0.0,
"specialAmountWithSecondUnit": -0.0
}
]
}
类
public class ItemStockLine
{
public int itemId { get; set; }
public string itemCode { get; set; }
public string itemName { get; set; }
public string barcode { get; set; }
public double actualAmount { get; set; }
public double realAmount { get; set; }
public double specialAmount { get; set; }
public string unitName { get; set; }
public string secondUnitName { get; set; }
public double actualAmountWithSecondUnit { get; set; }
public double realAmountWithSecondUnit { get; set; }
public double specialAmountWithSecondUnit { get; set; }
}
public class Root
{
public List<ItemStockLine> itemStockLines { get; set; }
}
如果你想从负零转换为正整数,你可以使用这个代码
private double ConvertToDouble( string val)
{
var value=Convert.ToDouble(val);
return IsNegativeZero(value)? 0.0d : value;
}
private bool IsNegativeZero(double x)
{
return x == 0.0 && double.IsNegativeInfinity(1.0 / x);
}
测试
var stringValue= "-0";
var value = ConvertToDouble(stringValue); // value= 0
你可以这样用
SpecialAmount = ConvertToDouble(dr["SpecialAmount"]),
我研究了几天这个问题并找到了解决这个问题的方法。
我只将 0.0
(正零)添加到数据库读取的结果中。
例如:
ActualAmount = Convert.ToDouble(dr["ActualAmount"]) + 0.0
我测试了这个解决方案,它运行良好:
using Newtonsoft.Json;
using System;
var str = "-0";
var double1 = Convert.ToDouble(str);
var double2 = Convert.ToDouble(str) + 0.0;
var serializedDouble1 = JsonConvert.SerializeObject(double1);
var serializedDouble2 = JsonConvert.SerializeObject(double2);
Console.WriteLine($"serializedDouble1: {serializedDouble1}");
Console.WriteLine($"serializedDouble2: {serializedDouble2}");
结果:
注意:此解决方案的最佳方法是将插入数据的SQL脚本更改为table。
例如:
INSERT INTO MyTable(ActualAmount) VALUES(@actualAmount + 0.0)
感谢大家
我有一个 ASP.NET 5 Web API
项目。我使用 MsSql 2016
数据库。我从数据库中获取数据并通过 API return 将其发送到应用程序。但我有一个问题。 API returns 0
喜欢 -0.0
(负零)
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyDbContext>(options => options.UseSqlServer(ConfigManager.ConnectionString));
services.AddControllersWithViews().AddNewtonsoftJson();
services.AddSwaggerGen(c =>
{
c.OperationFilter<AddXUserIdRequiredHeaderParameter>();
//c.OperationFilter<AddXLanguageHeaderParameter>();
c.SwaggerDoc("v1", new OpenApiInfo { Title = "MyManagerWS", Version = "v1" });
// Set the comments path for the swagger json and ui.
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
c.IncludeXmlComments(xmlPath);
});
}
public class DbHelper {
public static GetDataOutput GetData(int userId, GetDataInput input)
{
var result = new ReportItemStockDataResponse();
string sqlQuery = @"SELECT ItemId,
ItemName,
ItemCode,
Barcode,
ActualAmount,
UnitName,
RealAmount,
SpecialAmount,
ActualAmountWithSecondUnit,
RealAmountWithSecondUnit,
SpecialAmountWithSecondUnit,
SecondUnitName,
FROM
MyTable";
try
{
using (var connDb = new SqlConnection(_connectionString))
{
connDb.Open();
using (var command = connDb.CreateCommand())
{
using (var dr = command.ExecuteReader())
{
while (dr.Read())
{
result.ItemStockLines.Add(
new ReportItemStockDataResponse.ItemStock()
{
ItemId = Convert.ToInt32(dr["ItemId"]),
ItemName = dr["ItemName"].ToString(),
ItemCode = dr["ItemCode"].ToString(),
Barcode = dr["Barcode"].ToString(),
ActualAmount = Convert.ToDouble(dr["ActualAmount"]),
UnitName = dr["UnitName"].ToString(),
RealAmount = Convert.ToDouble(dr["RealAmount"]),
SpecialAmount = Convert.ToDouble(dr["SpecialAmount"]),
ActualAmountWithSecondUnit = Convert.ToDouble(dr["ActualAmountWithSecondUnit"]),
RealAmountWithSecondUnit = Convert.ToDouble(dr["RealAmountWithSecondUnit"]),
SpecialAmountWithSecondUnit = Convert.ToDouble(dr["SpecialAmountWithSecondUnit"]),
SecondUnitName = dr["SecondUnitName"].ToString(),
});
}
}
}
}
}
catch (Exception ex)
{
_logger.Error(ex, "Error");
result = null;
}
return result;
}
}
var result=DbHelper.GetData();
var serializedResult = JsonConvert.SerializeObject(result);
序列化结果如下:
{
"itemStockLines": [
{
"itemId": 111222333,
"itemCode": "Test code",
"itemName": "Test item",
"barcode": "",
"actualAmount": -0.0,
"realAmount": -0.0,
"specialAmount": -0.0,
"unitName": "ADET",
"secondUnitName": "QUTU",
"actualAmountWithSecondUnit": -0.0,
"realAmountWithSecondUnit": -0.0,
"specialAmountWithSecondUnit": -0.0
}
]
}
但 actualAmount
、realAmount
、specialAmount
、actualAmountWithSecondUnit
、realAmountWithSecondUnit
、specialAmountWithSecondUnit
在 C# 和 DB 中为零。
注意: 这些是 C# 中的双变量
Microsoft.AspNetCore.Mvc.NewtonsoftJson版本为5.0.3
感谢您的帮助
我不期待任何赞成票或反对票。仅供参考。
谁想了解更多关于符号零的信息我可以推荐 和 https://en.wikipedia.org/wiki/Signed_zero
我做了这个测试只是为了记录。对我来说,结果看起来很有趣。我反序列化了 PO json 并使用 NewtonsoftJson 再次对其进行了序列化。所有负零双打仍然是负数
var jsonDeserealized=JsonConvert.DeserializeObject<Root>(json);
var jsonReversed=JsonConvert.SerializeObject(jsonDeserealized);
结果
{
"itemStockLines": [
{
"itemId": 111222333,
"itemCode": "Test code",
"itemName": "Test item",
"barcode": "",
"actualAmount": -0.0,
"realAmount": -0.0,
"specialAmount": -0.0,
"unitName": "ADET",
"secondUnitName": "QUTU",
"actualAmountWithSecondUnit": -0.0,
"realAmountWithSecondUnit": -0.0,
"specialAmountWithSecondUnit": -0.0
}
]
}
类
public class ItemStockLine
{
public int itemId { get; set; }
public string itemCode { get; set; }
public string itemName { get; set; }
public string barcode { get; set; }
public double actualAmount { get; set; }
public double realAmount { get; set; }
public double specialAmount { get; set; }
public string unitName { get; set; }
public string secondUnitName { get; set; }
public double actualAmountWithSecondUnit { get; set; }
public double realAmountWithSecondUnit { get; set; }
public double specialAmountWithSecondUnit { get; set; }
}
public class Root
{
public List<ItemStockLine> itemStockLines { get; set; }
}
如果你想从负零转换为正整数,你可以使用这个代码
private double ConvertToDouble( string val)
{
var value=Convert.ToDouble(val);
return IsNegativeZero(value)? 0.0d : value;
}
private bool IsNegativeZero(double x)
{
return x == 0.0 && double.IsNegativeInfinity(1.0 / x);
}
测试
var stringValue= "-0";
var value = ConvertToDouble(stringValue); // value= 0
你可以这样用
SpecialAmount = ConvertToDouble(dr["SpecialAmount"]),
我研究了几天这个问题并找到了解决这个问题的方法。
我只将 0.0
(正零)添加到数据库读取的结果中。
例如:
ActualAmount = Convert.ToDouble(dr["ActualAmount"]) + 0.0
我测试了这个解决方案,它运行良好:
using Newtonsoft.Json;
using System;
var str = "-0";
var double1 = Convert.ToDouble(str);
var double2 = Convert.ToDouble(str) + 0.0;
var serializedDouble1 = JsonConvert.SerializeObject(double1);
var serializedDouble2 = JsonConvert.SerializeObject(double2);
Console.WriteLine($"serializedDouble1: {serializedDouble1}");
Console.WriteLine($"serializedDouble2: {serializedDouble2}");
结果:
注意:此解决方案的最佳方法是将插入数据的SQL脚本更改为table。
例如:
INSERT INTO MyTable(ActualAmount) VALUES(@actualAmount + 0.0)
感谢大家