Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Is it possible to customize the way types are serialized to the response in ASP.NET Core MVC?

In my particular use case I've got a struct, AccountId, that simply wraps around a Guid:

public readonly struct AccountId
{
    public Guid Value { get; }

    // ... 
}

When I return it from an action method, unsurprisingly, it serializes to the following:

{ "value": "F6556C1D-1E8A-4D25-AB06-E8E244067D04" }

Instead, I'd like to automatically unwrap the Value so it serializes to a plain string:

"F6556C1D-1E8A-4D25-AB06-E8E244067D04"

Can MVC be configured to achieve this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
189 views
Welcome To Ask or Share your Answers For Others

1 Answer

You can customize the output produced by JSON.NET with a custom converter.

In your case, it would look like this:

[JsonConverter(typeof(AccountIdConverter))]
public readonly struct AccountId
{
    public Guid Value { get; }

    // ... 
}

public class AccountIdConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
        => objectType == typeof(AccountId);

    // this converter is only used for serialization, not to deserialize
    public override bool CanRead => false;

    // implement this if you need to read the string representation to create an AccountId
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        => throw new NotImplementedException();

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (!(value is AccountId accountId))
            throw new JsonSerializationException("Expected AccountId object value.");

        // custom response 
        writer.WriteValue(accountId.Value);
    }
}

If you prefer not to use the JsonConverter attribute, it's possible to add converters in ConfigureServices (requires Microsoft.AspNetCore.Mvc.Formatters.Json):

public void ConfigureServices(IServiceCollection services)
{
    services
        .AddMvc()
        .AddJsonOptions(options => {
            options.SerializerSettings.Converters.Add(new AccountIdConverter());
        });
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...