将字节数组序列化为字符串

时间:2016-11-04 19:00:56

标签: c# json.net

我的代码中需要一个4字节数组的IP地址。但是我想将它作为字符串存储在我的JSON设置文件中,格式为“192.168.0.1”。然后我也想反过来反序列化它。

我想这样做,因为我的Settings.json文件的目标是它是人类可编辑的。

我有办法做到这一点吗?

我正在使用Newtonsoft JSON包

我正在序列化

public class Settings
{
    public string PLCIP;
    public byte[] RightTesterIP;
    public byte[] LeftTesterIP;
}
我写的转换器方法。只是不确定在哪里实施它们。

private string ConvertIPByteArraytoString(byte[] ip)
{
    StringBuilder builder = new StringBuilder();

    builder.Append(ip[0]);

    for (int i = 1; i < ip.Length; i++)
    {
        builder.Append(".");
        builder.Append(ip[i]);

    }
    return builder.ToString();
}

private byte[] ConvertIPStringToByteArray(string ip, string ParameterName)
{
    var blah = new byte[4];

    var split = ip.Split('.');

    if (split.Length != 4)
    {
        //Log.Error("IP Address in settings does not have 4 octets.Number Parsed was {NumOfOCtets}", split.Length);
        //throw new SettingsParameterException($"IP Address in settings does not have 4 octets. Number Parsed was {split.Length}");
    }

    for(int i = 0; i < split.Length; i++)
    {
        if(!byte.TryParse(split[i], out blah[i]))
        {
            //var ex = new SettingsParameterException($"Octet {i + 1} of {ParameterName} could not be parsed to byte. Contained \"{split[i]}\"");
            //Log.Error(ex,"Octet {i + 1} of {ParameterName} could not be parsed to byte. Contained \"{split[i]}\"", i, ParameterName, split[i]);
            //throw ex;
        }

    }

    return blah;
}

1 个答案:

答案 0 :(得分:2)

你可以像custom JsonConverter那样:

public class IPByteArrayConverter : JsonConverter
{
    private static string ConvertIPByteArraytoString(byte[] ip)
    {
        StringBuilder builder = new StringBuilder();

        builder.Append(ip[0]);

        for (int i = 1; i < ip.Length; i++)
        {
            builder.Append(".");
            builder.Append(ip[i]);

        }
        return builder.ToString();
    }

    private static byte[] ConvertIPStringToByteArray(string ip)
    {
        var blah = new byte[4];

        var split = ip.Split('.');

        if (split.Length != 4)
        {
            //Log.Error("IP Address in settings does not have 4 octets.Number Parsed was {NumOfOCtets}", split.Length);
            //throw new SettingsParameterException($"IP Address in settings does not have 4 octets. Number Parsed was {split.Length}");
        }

        for (int i = 0; i < split.Length; i++)
        {
            if (!byte.TryParse(split[i], out blah[i]))
            {
                //var ex = new SettingsParameterException($"Octet {i + 1} of {ParameterName} could not be parsed to byte. Contained \"{split[i]}\"");
                //Log.Error(ex,"Octet {i + 1} of {ParameterName} could not be parsed to byte. Contained \"{split[i]}\"", i, ParameterName, split[i]);
                //throw ex;
            }

        }

        return blah;
    }

    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var token = JToken.Load(reader);
        if (token.Type == JTokenType.Bytes)
            return (byte[])token;
        return ConvertIPStringToByteArray((string)token);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var bytes = (byte[])value;
        writer.WriteValue(ConvertIPByteArraytoString(bytes));
    }
}

然后,您可以使用[JsonConverter(IPByteArrayConverter)]将其附加到相应的属性或字段:

public class Settings
{
    public string PLCIP;
    [JsonConverter(typeof(IPByteArrayConverter))]
    public byte[] RightTesterIP;
    [JsonConverter(typeof(IPByteArrayConverter))]
    public byte[] LeftTesterIP;
}

示例fiddle

<强>更新

根据@Greg的建议使用IPAddress可以获得对IPV6和IPV4的支持。此类型的JsonConverter如下所示:

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

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var token = JToken.Load(reader);
        if (token.Type == JTokenType.Bytes)
        {
            var bytes = (byte[])token;
            return new IPAddress(bytes);
        }
        else
        {
            var s = (string)token;
            return IPAddress.Parse(s);
        }
    }

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

然后像以前一样将其应用到Settings班级,或在JsonSerializerSettings.Converters中全局使用:

var jsonSettings = new JsonSerializerSettings
{
    Converters = new [] { new IPAddressConverter() },
};

var json = JsonConvert.SerializeObject(settings, jsonSettings);

使用课程:

public class Settings
{
    public string PLCIP;
    public IPAddress RightTesterIP;
    public IPAddress LeftTesterIP;
}

示例fiddle