<i id='7ZaYf'><tr id='7ZaYf'><dt id='7ZaYf'><q id='7ZaYf'><span id='7ZaYf'><b id='7ZaYf'><form id='7ZaYf'><ins id='7ZaYf'></ins><ul id='7ZaYf'></ul><sub id='7ZaYf'></sub></form><legend id='7ZaYf'></legend><bdo id='7ZaYf'><pre id='7ZaYf'><center id='7ZaYf'></center></pre></bdo></b><th id='7ZaYf'></th></span></q></dt></tr></i><div id='7ZaYf'><tfoot id='7ZaYf'></tfoot><dl id='7ZaYf'><fieldset id='7ZaYf'></fieldset></dl></div>
<tfoot id='7ZaYf'></tfoot>

    1. <legend id='7ZaYf'><style id='7ZaYf'><dir id='7ZaYf'><q id='7ZaYf'></q></dir></style></legend>
      • <bdo id='7ZaYf'></bdo><ul id='7ZaYf'></ul>

      <small id='7ZaYf'></small><noframes id='7ZaYf'>

      1. 在 Newtonsoft.Json 中处理十进制值

        时间:2023-08-24
        <legend id='vw8jd'><style id='vw8jd'><dir id='vw8jd'><q id='vw8jd'></q></dir></style></legend>
            <bdo id='vw8jd'></bdo><ul id='vw8jd'></ul>

            <small id='vw8jd'></small><noframes id='vw8jd'>

              <tfoot id='vw8jd'></tfoot>

              <i id='vw8jd'><tr id='vw8jd'><dt id='vw8jd'><q id='vw8jd'><span id='vw8jd'><b id='vw8jd'><form id='vw8jd'><ins id='vw8jd'></ins><ul id='vw8jd'></ul><sub id='vw8jd'></sub></form><legend id='vw8jd'></legend><bdo id='vw8jd'><pre id='vw8jd'><center id='vw8jd'></center></pre></bdo></b><th id='vw8jd'></th></span></q></dt></tr></i><div id='vw8jd'><tfoot id='vw8jd'></tfoot><dl id='vw8jd'><fieldset id='vw8jd'></fieldset></dl></div>

                <tbody id='vw8jd'></tbody>

                1. 本文介绍了在 Newtonsoft.Json 中处理十进制值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  已经快 5 年了,我不认为这是要走的路.客户应以正确的数字格式发布数据.使用 React 或 Angular 等当前框架,或者使用适当的架构和错误处理和验证,我认为这几乎不是问题.

                  It's been almost 5 years and I don't think this is the way to go. The client should post the data in the correct numerical format. With current frameworks like React or Angular, or with a proper architecture and error handling & validation, i think this is almost a non-problem.

                  但是,如果有人想展示他们的 Json.NET 肌肉,请随时查看答案.

                  But if anyone wishes to flex their Json.NET muscles, feel free to check the answers.

                  我有一个 MVC 应用程序,我在其中处理了一些 JSON.这很简单.我的 ModelBinder 中有这段简单的代码:

                  I have a MVC application and I handle some JSON in it. That's simple. I have this simple piece of code in my ModelBinder:

                  return JsonConvert.DeserializeObject(jsonString, bindingContext.ModelType, new JsonSerializerSettings
                  {
                      NullValueHandling = NullValueHandling.Ignore,
                      MissingMemberHandling = MissingMemberHandling.Ignore,
                      Formatting = Formatting.None,
                      DateFormatHandling = DateFormatHandling.IsoDateFormat,
                      FloatParseHandling = FloatParseHandling.Decimal
                  });
                  

                  而且它完美无瑕.

                  嗯,有点.

                  假设我有这个课程:

                  public class MyClass
                  {
                      public decimal MyProp { get; set; }
                  }
                  

                  如果我尝试反序列化这个 json:

                  If I try to deserialize this json:

                  "{"MyProp": 9888.77}"
                  

                  当然可以,因为 9888.77 是 Javascript 浮点值.我想.

                  Of course it works, since 9888.77 is a Javascript float value. I think.

                  但是我的页面中有一个蒙面的钱输入,使 JSON 看起来像这样(对不起我的英语):

                  But I have a masked input for money in my page that makes the JSON look like this (sorry about my english):

                  "{"MyProp": "9.888,77" }"
                  

                  AAAND,它失败了.它说它无法将字符串转换为十进制.

                  AAAND, it fails. It says that it Could not convert string to decimal.

                  好的,这很公平.它不是 JS 浮点数,但 Convert.ToDecimal("9.888,77") 按我想要的方式工作.

                  Ok, that's fair. It is not a JS float, but Convert.ToDecimal("9.888,77") works the way I want.

                  我在互联网上阅读了一些关于自定义反序列化器的教程,但对我来说,为我的应用程序中的每个类定义一个自定义反序列化器是不可行的.

                  I've read some tutorials on the internet about custom deserializers, but its inviable for me to define a custom deserializer for every single class I have in my application.

                  我想要的是简单地重新定义 JSON.Net 将字符串转换为十进制属性的方式,在我想要反序列化的任何类中.我想在转换小数的过程中注入Convert.ToDecimal函数,此时当前转换器不起作用.

                  What I want is to simple redefine the way JSON.Net converts a string to a decimal property, in any class i'll ever want to deserialize to. I want to inject the Convert.ToDecimal function in the process of converting decimals, when the current converter doesn't work.

                  有什么办法可以做到吗?

                  Is there a way I could do it?

                  我认为有办法做到这一点,所以我稍微更改了我的代码.

                  I thought there was a way to do it, so I changed my code a little bit.

                  JsonSerializer serializer = new JsonSerializer
                  {
                      NullValueHandling = NullValueHandling.Ignore,
                      MissingMemberHandling = MissingMemberHandling.Ignore,
                      Formatting = Formatting.None,
                      DateFormatHandling = DateFormatHandling.IsoDateFormat,
                      FloatParseHandling = FloatParseHandling.Decimal,
                  };
                  
                  
                  
                  return serializer.Deserialize(new DecimalReader(jsonStr), bindingContext.ModelType);
                  

                  并创建了这个类:

                  public class DecimalReader : JsonTextReader
                  {
                      public DecimalReader(string s)
                          : base(new StringReader(s))
                      {
                      }
                  
                      public override decimal? ReadAsDecimal()
                      {
                          try
                          {
                              return base.ReadAsDecimal();
                          }
                          catch (Exception)
                          {
                              if (this.TokenType == JsonToken.String)
                              {
                                  decimal value = 0;
                  
                                  bool convertible = Decimal.TryParse(this.Value.ToString(), out value);
                  
                                  if (convertible)
                                  {
                                      return new Nullable<decimal>(value);
                                  }
                                  else { throw; }
                              }
                              else
                              {
                                  throw;
                              }
                          }
                      }
                  }
                  

                  但它非常丑陋:它只在崩溃时执行我想要的,并且依赖于 base.ReadAsDecimal() 崩溃.简直不能更丑了.

                  But it is very ugly: it executes what I want only when it crashes, and depends on base.ReadAsDecimal() crashing. It couldn't be more ugly.

                  而且不起作用:将值1.231,23"转换为类型System.Nullable1[System.Decimal]"时出错.路径MyProp",X 行,Y 位置.

                  值本身正在被转换,但可能出于某种原因它仍然尝试将字符串1.231,23"转换为小数.

                  The value itself is being converted, but perhaps for some reason it still tries to put the string "1.231,23" into a decimal.

                  那么,有没有办法正确地做到这一点?

                  So, is there a way to do it properly?

                  推荐答案

                  您可以使用像这样的自定义 JsonConverter 类处理这两种格式(JSON 数字表示和屏蔽字符串格式).p>

                  You can handle both formats (the JSON number representation and the masked string format) using a custom JsonConverter class like this.

                  class DecimalConverter : JsonConverter
                  {
                      public override bool CanConvert(Type objectType)
                      {
                          return (objectType == typeof(decimal) || objectType == typeof(decimal?));
                      }
                  
                      public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
                      {
                          JToken token = JToken.Load(reader);
                          if (token.Type == JTokenType.Float || token.Type == JTokenType.Integer)
                          {
                              return token.ToObject<decimal>();
                          }
                          if (token.Type == JTokenType.String)
                          {
                              // customize this to suit your needs
                              return Decimal.Parse(token.ToString(), 
                                     System.Globalization.CultureInfo.GetCultureInfo("es-ES"));
                          }
                          if (token.Type == JTokenType.Null && objectType == typeof(decimal?))
                          {
                              return null;
                          }
                          throw new JsonSerializationException("Unexpected token type: " + 
                                                                token.Type.ToString());
                      }
                  
                      public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
                      {
                          throw new NotImplementedException();
                      }
                  }
                  

                  要将其插入您的活页夹,只需将转换器的一个实例添加到 JsonSerializerSettings 对象的 Converters 列表中:

                  To plug this into your binder, just add an instance of the converter to the Converters list in the JsonSerializerSettings object:

                  JsonSerializerSettings settings = new JsonSerializerSettings
                  {
                      NullValueHandling = NullValueHandling.Ignore,
                      MissingMemberHandling = MissingMemberHandling.Ignore,
                      Formatting = Formatting.None,
                      DateFormatHandling = DateFormatHandling.IsoDateFormat,
                      Converters = new List<JsonConverter> { new DecimalConverter() }
                  };
                  

                  这篇关于在 Newtonsoft.Json 中处理十进制值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:如何从 Json.NET 获取密钥列表? 下一篇:如何将 unix 时间戳 (μs) 从 JSON 反序列化为 DateT

                  相关文章

                  最新文章

                2. <small id='QLvU0'></small><noframes id='QLvU0'>

                  <i id='QLvU0'><tr id='QLvU0'><dt id='QLvU0'><q id='QLvU0'><span id='QLvU0'><b id='QLvU0'><form id='QLvU0'><ins id='QLvU0'></ins><ul id='QLvU0'></ul><sub id='QLvU0'></sub></form><legend id='QLvU0'></legend><bdo id='QLvU0'><pre id='QLvU0'><center id='QLvU0'></center></pre></bdo></b><th id='QLvU0'></th></span></q></dt></tr></i><div id='QLvU0'><tfoot id='QLvU0'></tfoot><dl id='QLvU0'><fieldset id='QLvU0'></fieldset></dl></div>
                  • <bdo id='QLvU0'></bdo><ul id='QLvU0'></ul>

                  <legend id='QLvU0'><style id='QLvU0'><dir id='QLvU0'><q id='QLvU0'></q></dir></style></legend>

                    1. <tfoot id='QLvU0'></tfoot>