4

我有一堂课:

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

默认情况下,http://localhost:1234/swaggerNswag.AspNetCore上的 Nswag (包)将其序列化,在预览“示例”输出中:

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

我想对其进行自定义,以便它仅将 Ip 字段序列化为 astring而没有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“示例”输出时Test,它仍然包括所有属性,IPAddress而不是Ip字段被序列化为简单的string.

当我调试时,我可以看到里面的代码CustomSwaggerContractResolver被调用,并且转换器被分配,但它IPAddressConverter本身从未被调用。

有什么我想念的吗?

谢谢你。

4

1 回答 1

5

因为转换器的转换不能被反映(它是程序的)你需要添加一个类型映射器

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

并将 ipaddress 类型映射到简单的字符串模式

(NJsonSchema 是 NSwag 的基础)

于 2018-05-08T22:19:35.400 回答