jsakamoto/ipaddressrange

[Breaking Change] Truncate .NET4.0 support for improving JSON serialization by JSON.NET

Closed this issue · 1 comments

Problem

An IPAddressRange after v.1.4 object cann't serialize to/deserialize from JSON text by using JSON.NET.

Details

JSON.NET detect IEnumerable<IPAddress> interface prior to ISerializable.
At a result, JSON.NET try to serialize IPAddressRange as array, such as "["192.168.0.1", "192.168.0.2"]".
This is unexpected behavior. (We expect "{"Begin":"192.168.0.1", "End:"192.168.0.2"}" style JSON text that is same with DataContractJsonSerializer.)
In addition, JSON serialization with JSON.NET crash due to IPAddress cann't serialize by JSON.NET.

Work around

To avoid this JSON.NET behavior, IPAddressRange should implement more high priority interface than IEnumerable<T> in JSON.NET.
Such interfaces include the following.

  • IDictionary
  • IDictionary<TKey,TVal>
  • IReadOnlyDictionary<TKey,TVal>
    But, when IPAddressRange implement IDictionay or IDictionary<TKey,TVal>, serialization by DataContractJsonSerializer was broken.
    (Implementation of DataContractJsonSerializer is specialized for IDictionay and IDictionary<TKey,TVal>)

So there is no way without implement IReadOnlyDictionary<TKey,TVal>.

Trade off

IReadOnlyDictionary<TKey,TVal> interface doesn't exist in .NET Framework v.4.0 or before.

In order to give priority to supporting serialization by JSON.NET, I had to truncate the support for .NET Framework 4.0.
(.NET Standard 1.4 support IReadOnlyDictionary<TKey,TVal>, therefore there is no problem on .NET Core appliction.)

Binary level compatiblity

There will be no problem even if IPAddressRange.dll is replaced with the latest version.

Source code level compatiblity

You cann't apply LINQ extension methods directory to IPAddressRange object like this:

var texts = IPAddressRange.Parse("192.168.0.0/24")
    .Select(ip => ip.ToString());

Because IPAddressRange implement two types of IEnumerable<T> (IEnumerable<IPaddress> and IEnumerable<KeyValuePair<K,V>>).
It cause ambiguous compile error.

To avoid this error, you should use "AsEnumerable()" method before IEnumerable<IPAddressRange> access.

var texts = IPAddressRange.Parse("192.168.0.0/24")
    .AsEnumerable() // insert this
    .Select(ip => ip.ToString());

Plan

I'm considering to release this change as IPAddressRange ver.2.0 after a few days or around a week.