NSwag自定义JSON输出

时间:2018-02-05 12:20:40

标签: c# asp.net-web-api swagger nswag

我有一个班级:

class Test {
  public IPAddress Ip {get; set; }
}

默认情况下,http://localhost:1234/swagger处的Nswag(Nswag.AspNetCore包)将其序列化为预览"示例"输出:

[    
  "Ip": {
     "AddressFamily": 0,
     "ScopeId": 0,
     "IsIPv6Multicast": true,
     "IsIPv6LinkLocal": true,
     "IsIPv6SiteLocal": true,
     "IsIPv6Teredo": true,
     "IsIPv4MappedToIPv6": true,
     "Address": 0
    }
]

我希望对其进行优化,以便将Ip字段序列化为string而不使用IPAddress的所有其他类型属性。

为此,我创建了自己的JsonConverter

public class IPAddressConverter : JsonConverter
{ 
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(IPAddress));
    }

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    { 
        return IPAddress.Parse((string)reader.Value);
    }
}

并确认它适用于JSON.Net。

var settings = new JsonSerializerSettings() { Converters =  { new IPAddressConverter() } };
JsonConvert.SerializeObject(IPAddress.Parse("123.123.123.123"), settings);
JsonConvert.DeserializeObject<IPAddress>("123.123.123.123", settings);

现在我想把它插入NSwag。我在ASP.Net的Startup.cs中修改了NSwag设置:

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();

        var swaggerSettings = new SwaggerUi3Settings()
        { 
            ContractResolver = new CustomSwaggerContractResolver(),
            DefaultPropertyNameHandling = NJsonSchema.PropertyNameHandling.Default /* If this is not set to default it raises an exception when a ContractResolver is set and then swagger page does not load at all */
        };

        app.UseSwaggerUi3(typeof(Startup).Assembly, swaggerSettings);
 }

public class CustomSwaggerContractResolver : DefaultContractResolver
{   
    protected override JsonContract CreateContract(Type objectType)
    {  
        JsonContract contract = base.CreateContract(objectType);

        if (objectType == typeof(IPAddress))
        {
            contract.Converter = new IPAddressConverter();
        }  

        return contract;
    }
} 

不幸的是,当我浏览http://localhost:1234/swagger以查看Json&#34;示例&#34;我的Test类的输出仍然包含IPAddress的所有属性,而不是Ip字段被序列化为简单的string

当我调试时,我可以看到调用CustomSwaggerContractResolver内的代码,并且已分配转换器,但IPAddressConverter本身永远不会被调用。

我有什么遗失的吗?

谢谢。

1 个答案:

答案 0 :(得分:1)

因为无法反映转换器的转换(它是程序性的),所以需要添加类型映射器

https://github.com/RSuter/NJsonSchema/wiki/Type-Mappers

并将ipaddress类型映射到简单的字符串架构

(NJsonSchema是NSwag的基地)