在ASP.NET Core MVC中自定义响应序列化

Mic*_*dak 13 c# asp.net-core-mvc asp.net-core

是否可以自定义类型序列化为ASP.NET Core MVC中的响应的方式?

在我的特定用例中,我有一个结构,AccountId它只包含一个Guid:

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

    // ... 
}
Run Code Online (Sandbox Code Playgroud)

当我从动作方法返回它时,不出所料,它序列化为以下内容:

{ "value": "F6556C1D-1E8A-4D25-AB06-E8E244067D04" }
Run Code Online (Sandbox Code Playgroud)

相反,我想自动解包,Value所以它序列化为一个普通的字符串:

"F6556C1D-1E8A-4D25-AB06-E8E244067D04"
Run Code Online (Sandbox Code Playgroud)

可以配置MVC来实现这一目标吗?

Mét*_*ule 26

您可以使用自定义转换器自定义 JSON.NET生成的输出.

在你的情况下,它看起来像这样:

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不想使用该JsonConverter属性,可以在ConfigureServices(要求Microsoft.AspNetCore.Mvc.Formatters.Json)中添加转换器:

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

  • 这几乎就是我最终做到这一点的方式.我只是不喜欢`JsonConverter`属性,所以我将我的转换器添加到`ConfigureServices`'`AddMvc`中的`SerializerSettings.Converters` (4认同)
  • 为了完整起见,我已经在您的答案中添加了替代方法。 (2认同)