You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中强制将JSON特定属性反序列化为字符串类型(兼容数字与字符串输入)?

Solution for Mixed Numeric/String Id Deserialization in C#

Absolutely, you can solve this cleanly by creating a targeted JsonConverter<string> and applying it directly to your Id property via the [JsonConverter] attribute. This approach ensures only that specific property gets the custom deserialization logic, leaving all other properties (including nullable types, system types, and custom classes) to use default serialization behavior—exactly what you need.

Step 1: Create the Custom Converter

This converter will handle both numeric and string inputs, converting them to a string for your property. It also accounts for null values and avoids overflow issues by reading the raw value directly instead of parsing to a numeric type first.

For System.Text.Json (default in .NET Core 3.0+)

public class NumericToStringIdConverter : JsonConverter<string>
{
    public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // Handle null values
        if (reader.TokenType == JsonTokenType.Null)
        {
            return null;
        }

        // Convert numeric tokens directly to string
        if (reader.TokenType == JsonTokenType.Number)
        {
            // Use GetString() to read the raw numeric value as a string (avoids overflow)
            return reader.GetString();
        }

        // Return string tokens as-is
        if (reader.TokenType == JsonTokenType.String)
        {
            return reader.GetString();
        }

        // Throw an exception for unexpected token types (adjust if needed)
        throw new JsonException($"Unexpected token type {reader.TokenType} encountered for Id property.");
    }

    public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        // For serialization, write the string value directly
        writer.WriteStringValue(value);
    }
}

For Newtonsoft.Json (Json.NET)

If you're using the older Newtonsoft library, the converter looks slightly different:

public class NewtonsoftNumericToStringIdConverter : JsonConverter<string>
{
    public override string ReadJson(JsonReader reader, Type objectType, string existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;

        // Convert numeric types to string
        if (reader.TokenType is JsonToken.Integer or JsonToken.Float)
            return reader.Value.ToString();

        // Return string values as-is
        if (reader.TokenType == JsonToken.String)
            return (string)reader.Value;

        throw new JsonException($"Unexpected token type {reader.TokenType} encountered for Id property.");
    }

    public override void WriteJson(JsonWriter writer, string value, JsonSerializer serializer)
    {
        writer.WriteValue(value);
    }
}

Step 2: Apply the Converter to Your Property

Add the [JsonConverter] attribute directly to your Id property—this ensures the custom logic only runs for this specific property, not the entire model or application.

For System.Text.Json

public class Something
{
    // Apply the custom converter ONLY to this Id property
    [JsonConverter(typeof(NumericToStringIdConverter))]
    public string Id { get; set; }

    // Other properties use default serialization
    public int? NullableInteger { get; set; }
    public DateTimeOffset? NullableDate { get; set; }
    public CustomClass CustomProperty { get; set; }
}

// Example custom class
public class CustomClass
{
    public string Name { get; set; }
    public decimal Price { get; set; }
}

// Root model to match your JSON structure
public class RootModel
{
    public Something Something { get; set; }
}

For Newtonsoft.Json

Use the Newtonsoft-specific attribute:

public class Something
{
    [Newtonsoft.Json.JsonConverter(typeof(NewtonsoftNumericToStringIdConverter))]
    public string Id { get; set; }

    // Rest of your properties...
}

Step 3: Test the Deserialization

Both numeric and string-based Id values will now correctly deserialize to a string:

// Test with numeric Id
var numericJson = @"{""something"": {""id"": 123, ""nullableInteger"": 45, ""customProperty"": {""name"": ""Product"", ""price"": 9.99}}}";
var numericResult = JsonSerializer.Deserialize<RootModel>(numericJson);
// numericResult.Something.Id will be "123" (string)

// Test with string/GUID Id
var stringJson = @"{""something"": {""id"": ""ex.GUID-1234"", ""nullableDate"": ""2024-01-01T00:00:00Z"", ""customProperty"": {""name"": ""Service"", ""price"": 19.99}}}";
var stringResult = JsonSerializer.Deserialize<RootModel>(stringJson);
// stringResult.Something.Id will be "ex.GUID-1234" (string)

Why This Works Better Than Global Converters

  • Targeted Scope: Only the marked Id property uses the custom logic—no unintended side effects on other properties or models.
  • Robust Handling: Accounts for nulls, numeric values, and string values without throwing unnecessary exceptions.
  • Avoids Overflow: Using reader.GetString() for numeric tokens reads the raw value directly, preventing issues with large numbers that might overflow int or long types.

内容的提问来源于stack exchange,提问作者Eugene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 13:47:29