0

I receive an int from rest API I want json deserializer to put into string property "Hovednummer", but I receive an error saying can't convert from int to string.

I tried to fix this with a custom converter class I call IntToStringConverter. And I add a Json property to the property Hovednummer [JsonConverter(typeof(IntToStringConverter))].

But it doesn't work, when I debug the program it doesn't even enter any breakpoint in the custom converter class.

namespace CrownData.DataInteractionLayer.DanishCrown.Models
{
    public class StemDataReadDTO
    {
        [JsonConverter(typeof(IntToStringConverter))]
        public string Hovednummer { get; set; }
        public EjerStem Ejer { get; set; }
    }


    public class IntToStringConverter : Newtonsoft.Json.JsonConverter
    {
        public override bool CanConvert(Type typeToConvert)
        {
            return typeToConvert == typeof(string);
        }

        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public object IntToString(JsonReader reader) //, Type objectType, object existingValue, JsonSerializer serializer
        {
            if (reader.TokenType == JsonToken.Null)
                return null;
            if (reader.TokenType == JsonToken.String)
                return reader.Value;
            if (reader.TokenType == JsonToken.Integer)
                return reader.Value.ToString();

            throw new JsonReaderException(string.Format("Unexcepted token {0}", reader.TokenType));
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override string ToString()
        {
            return base.ToString();
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
  • TryGetStemData, getting data. This works, I get something. I just want the hovedenr datatype to stay string. Right now I'm forced to set it as int.

      public bool TryGetStemData(string hovedNummer, string cvrNummer, out Models.StemDataReadDTO stemData)
      {
          string url = _dcConfig.UrlStemData;
          StemDataCreateDTO payload = new()
          {
              CVRnr = cvrNummer,
              Hovednr = hovedNummer
          };
          var stemTask = GetClientDataAsPostAsync<Models.StemDataReadDTO>(url, payload);
          stemTask.Wait();
          stemData = stemTask.Result.result;
          return stemTask.Result.succes;
      }
    
  • GetClientDataAsPostAsync method, it's a generic method used for getting and validate reponses.

      private async Task<(bool succes, T result)> GetClientDataAsPostAsync<T>(string url, object payload, bool allowNull = false)
      {
          bool isValid = false;
          int MaxTimeout = 20;
          var cts = new CancellationTokenSource(TimeSpan.FromSeconds(MaxTimeout));
          T result = default;
          try
          {
              HttpResponseMessage response = await _client.PostAsJsonAsync(url, payload, _serializerOptions, cts.Token);
    
              if (response.IsSuccessStatusCode)
              {
                  result = await JsonSerializer.DeserializeAsync<T>(await response.Content.ReadAsStreamAsync());
                  if (result == null && !allowNull)
                  {
                      ErrorMessage = "Ugyldigt returdata";
                  }
                  else
                  {
                      isValid = true;
                  }
    
              }
              else
              {
                  ErrorMessage = (await response.Content.ReadAsStringAsync()) ?? response.ReasonPhrase;
              }
          }
          catch (TaskCanceledException e)
          {
              ErrorMessage = $"Timout: {e.Message}";
          }
          catch (Exception e)
          {
              ErrorMessage = e.Message;
          }
          return (isValid, result);
      }
    
  • I setting some options here, but I get the same error even with the numberHandling set to Write as string.

          _serializerOptions = new JsonSerializerOptions()
          {
              PropertyNamingPolicy = null,
              NumberHandling = (System.Text.Json.Serialization.JsonNumberHandling.WriteAsString),
          };
    
TSS
  • 21
  • 3
  • 2
    Please read [ask], where it says "**DO NOT post images of code, data, error messages, etc.** - copy or type the text into the question." – Heretic Monkey Aug 31 '21 at 12:07
  • 1
    My apologies, I have changed it. I wanted to showcase I had breakpoints, and that I didn't reach any of them when running the code. – TSS Aug 31 '21 at 12:17
  • 1
    Please provide context to your question. How are you calling this piece of code? I doubt the problem is in your converter class. Rather it's probably about how you configured the Serializer. – AsPas Aug 31 '21 at 12:19
  • 1
    I have provided some context. – TSS Aug 31 '21 at 12:38
  • 1
    _client.PostAsJsonAsync should start the deserialation when they send response return, – TSS Aug 31 '21 at 12:39
  • Do you have a string in C# and you want it to be a number in JSON? Or do you have an int in C# and you want it to be a string in JSON? Because your `IntToStringConverter` does the former (it converts from a number in JSON to a string in C#), while your serializer settings (`JsonNumberHandling.WriteAsString`) indicate the latter (it writes numbers as strings). The serializer settings are meaningless if your class has defined the property as string of course. I don't think I've ever had an issue with having a JSON number go into a string property though. – Heretic Monkey Aug 31 '21 at 16:02
  • You seem to be mixing types from two different serializers. [`IntToStringConverter : Newtonsoft.Json.JsonConverter`](https://www.newtonsoft.com/json/help/html/t_newtonsoft_json_jsonconvert.htm) is from [tag:json.net] but [`JsonSerializerOptions`](https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions) is from [tag:system.text.json]. That's not going to work, you need to consistently use types from the same serializer. But which serializer are you using? Do you know? What version of [tag:asp.net] are you using, and how are you configuring it? – dbc Aug 31 '21 at 16:08
  • Also, please [edit] your question to share a JSON string that reproduces the problem -- i.e. a full [mcve]. – dbc Aug 31 '21 at 16:11
  • If you are using [tag:system.text.json] see [System.Text.Json: Deserialize JSON with automatic casting](https://stackoverflow.com/q/59097784/3744182). In fact this may be a duplicate, agree? – dbc Aug 31 '21 at 16:15

0 Answers0