"type mismatch during model binding"
Firstly,
Price
value here is a
string
:
"Price": "28.78",
Yet you define you proerty in your class as a
decimal
type.
Yes you have a "type mismatch" error. The error message is very explicit:
Message=The JSON value could not be converted to System.Nullable`1[System.Decimal]. Path: $.Config.Price | LineNumber: 3 | BytePositionInLine: 24.
You will need to write a custom converter to convert between value types. The alternative, if possible, is to correctly serialize the value as a number. This is the prefered option if possible. It should look like this:
"Price": 28.78,
Here is how to write a custom converter for the
System.Text.Json
namespace. Newtownsoft Custom Converters are a little bit different - you can learn more here:
Working with JSON in C# & VB[
^]
public class StringToDecimalConverter : JsonConverter<decimal>
{
public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
decimal.TryParse(reader.GetString()!, out decimal value);
return value;
}
public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
There are two ways that you can use the Custom Converter:
1.
JsonSerializerOptions
2. As a Property Atteribute.
You can read more about Custom Converters here:
How to write custom converters for JSON serialization - .NET | Microsoft Docs[
^] - there are how-to examples.
Here we will use Property Attributes:
public class Config
{
public string? State { get; set; }
[JsonConverter(typeof(StringToDecimalConverter))]
public decimal? Price { get; set; }
[JsonConverter(typeof(StringToDecimalConverter))]
public decimal? discount { get; set; }
public Order? Order { get; set; }
}
Now the
Price
and
discount
properties will not throw errors.
The next issue that you have is your
saletype
property. This will throw a similar error as you cannot convert String to Enum. Luckily, there is a pre-built
JsonStringEnumConverter
class. You can read more here:
https://docs.microsoft.com/en-us/dotnet/api/system.text.json.serialization.jsonstringenumconverter?view=net-6.0[
^]. This is staight forward to use:
public enum SaleType
{
COD,
ONLINE,
PICKUP,
OTHER
}
public class Order
{
[JsonConverter(typeof(JsonStringEnumConverter))]
public SaleType? saletype { get; set; }
}
The last issue that you have is your
Order.itemid
property. You can not convert a
string
to an
int
. I have written the
StringToDecimalConverter
converter for you,
StringToIntegerConverter
I will leave to you.
** UPDATE **
For Completeness, here is my test code:
1.
Program.cs
(dot net 6.0)
using System.Diagnostics;
using System.Text.Json;
string json =
@"{
""Config"": {
""State"": ""combodia"",
""Price"": ""28.78"",
""discount"": """",
""Order"": {
""saletype"": ""PICKUP""
}
}
}";
var data = JsonSerializer.Deserialize<Root>(json);
Debugger.Break();
2. Classes used:
using System.Text.Json.Serialization;
public enum SaleType
{
COD,
ONLINE,
PICKUP,
OTHER
}
public class Order
{
[JsonConverter(typeof(JsonStringEnumConverter))]
public SaleType? saletype { get; set; }
}
public class Config
{
public string? State { get; set; }
[JsonConverter(typeof(StringToDecimalConverter))]
public decimal? Price { get; set; }
[JsonConverter(typeof(StringToDecimalConverter))]
public decimal? discount { get; set; }
public Order? Order { get; set; }
}
public class Root
{
public Config? Config { get; set; }
}
public class StringToDecimalConverter : JsonConverter<decimal>
{
public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
decimal.TryParse(reader.GetString()!, out decimal value);
return value;
}
public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
Code runs and deserializes successfully.