Serializing .MinValue value types (C #) in ASP.NET Web API 2 for null

I would like to serialize .MinValue value types (C #) in ASP.NET Web API 2 to null when passed to the client. When a client sends a value with a null value, I would like to get .MinValue for the value types on the server.

I am using Json.Net to serialize and deserialize Json. Next, I need the same thing for the URI parameters, and possibly formdata as well. I need the following types: short, int, long, float, double, decimal, DateTime

Things I tried:

  • One solution is to work with NULL types. But on the server, I prefer to work with types with a null value, because the business logic layer works with type values, and at the data access level they are converted to DBNull if they are .MinValue.
  • I wrote a JsonConverter for DateTime (derived from IsoDateTimeconverter) to treat DateTime.MinValue as null and vice versa. This works great, but I'm not sure how to do it with Numbers, because they do not have JsonConverter implementations in Json.Net or I cannot find them.
  • For URI parameters I will try to execute ImodelBinder

Is there a built-in way in Json.Net to handle my needs that I have not found?

How can I overwrite serial serialization (int, decimal, ..) in Json.Net?

Any other idea to meet my needs ...

+4
source share
1 answer

To do this, you can use your own converter:

public class ValueTypeConverter : JsonConverter
{
    private static List<Type> SupportedTypes = new List<Type>
    {
        typeof(short),
        typeof(int),
        typeof(long),
        typeof(float),
        typeof(double),
        typeof(decimal),
        typeof(DateTime)
    };

    private static Dictionary<Type, object> MinValues;

    static ValueTypeConverter()
    {
        MinValues = new Dictionary<Type, object>();

        foreach (Type type in SupportedTypes)
        {
            MinValues.Add(type, GetMinValue(type));
        }
    }

    public override object ReadJson(
        JsonReader reader, 
        Type objectType,
        object existingValue,
        JsonSerializer serializer)
    {
        object value = reader.Value;

        value = value ?? MinValues[objectType];
        value = Convert.ChangeType(value, objectType);

        return value;
    }

    public override bool CanConvert(Type objectType)
    {
        return MinValues.ContainsKey(objectType);
    }

    public override void WriteJson(
        JsonWriter writer, object value, JsonSerializer serializer)
    {        
        object minValue = MinValues[value.GetType()];

        if (object.Equals(value, minValue))
        {
            value = null;
        }

        writer.WriteValue(value);
    }

    private static object GetMinValue(Type objectType)
    {
        FieldInfo minValueFieldInfo = objectType.GetField("MinValue");

        return minValueFieldInfo.GetValue(null);
    }
}

Using:

var settings = new JsonSerializerSettings
{
    Converters = new[] { new ValueTypeConverter() }
};

string json = JsonConvert.SerializeObject(obj, settings);

Example: https://dotnetfiddle.net/WPhJr5

+3
source

All Articles