本文介绍了如何让newtonsoft反序列化yes和no来布尔的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请注意:我提供这个饲料底部的解决方案

NOTE: I have provided the solution at the bottom of this feed.

我有一个C#赢8应用,在那里我反序列化一些JSON看起来像这样的:

I have a C# Win 8 app where I'm de-serializing some json that looks like this:

"{'Unit':[{'name':'House 123',isAvailable:'no'},{'name':'House 456',isAvailable:'yes'}]}"

into a class that uses this interface:

            public interface IUnit
            {
                string Name { get; }
                bool isAvailable { get; }
            }



但Newtonsoft抛出一个错误:

But Newtonsoft throws an error:

意外遇到字符在解析值:N。路径
'股[0] .isAvailable,1号线,42位。

有没有办法来Newtonsoft延伸到解析是/否或1/0的基础上产生的对象属性bool类型的?现在它仅适用于真/假。

Is there a way to extend Newtonsoft to parse yes/no or 1/0 based on the resulting object property type of bool? Right now it only works for true/false.

有对类的自定义转换器的几个职位,但不是一个原始类型像布尔。

There are several posts on custom converters for classes, but not a primitive type like bool.

有什么建议?

推荐答案

//这是我想出了...

//This is what I came up with...

   using System;
 using System.Collections.Generic;
 using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace NewtonTest
{

internal class NewtonTest
{
    public class Data
    {
        public IEnumerable<IUnit> Unit { get; set; }

        public override string ToString()
        {
            return string.Format("Data{{Unit=[{0}]}}",
                string.Join(", ", Unit.Select(c =>
                                string.Format("{0} - Single Unit: {1}", 
                                    c.Name,
                                    c.isSingleUnit.ToString()))));
        }
    }

    public interface IUnit
    {
        string Name { get; }

        // [JsonConverter(typeof(Converter))]
        bool isSingleUnit { get; }
    }

    public class House : IUnit
    {
        public House(string name, bool isSingle)
        {
            this.Name = name;
            this.isSingleUnit = isSingle;
        }

        public string Name { get; private set; }

        public bool isSingleUnit { get; private set; }
    }

    public class Apartment : IUnit
    {
        public Apartment(string name, bool isSingle)
        {
            this.Name = name;
            this.isSingleUnit = isSingle;
        }

        public string Name { get; private set; }

        public bool isSingleUnit { get; private set; }
    }

    private static bool ConvertToBool(string value)
    {
        value =
            value.ToUpper().
                  Replace("YES", "TRUE").
                  Replace("Y", "TRUE").
                  Replace("1", "TRUE").
                  Replace("NO", "FALSE").
                  Replace("N", "FALSE").
                  Replace("0", "FALSE");

        bool result = false;

        bool.TryParse(value, out result);

        return result;
    }


    private class UnitConverter : Newtonsoft.Json.JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof (NewtonTest.IUnit).IsAssignableFrom(objectType);
        }

        public override object ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object existingValue,
                                        Newtonsoft.Json.JsonSerializer serializer)
        {
            JObject obj = serializer.Deserialize<JToken>(reader) as JObject;

            if (obj != null)
            {
                string result = obj["isSingleUnit"].ToObject<string>();

                bool isSingleUnit = ConvertToBool(result);

                string name = obj["name"].ToObject<string>();

                if (isSingleUnit)
                {
                    return new NewtonTest.House(name, isSingleUnit);
                }
                else
                {
                    return new NewtonTest.Apartment(name, isSingleUnit);
                }
            }
            else
            {
                return null;
            }
        }

        public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object value,
                                       Newtonsoft.Json.JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }


    public static void Main()
    {
        Newtonsoft.Json.JsonSerializer serializer = new Newtonsoft.Json.JsonSerializer();
        serializer.Converters.Add(new UnitConverter());
        string json =
            "{'Unit':[{'name':'Apartment 123',isSingleUnit:'no'},{'name':'House 456',isSingleUnit:'yes'}]}".Replace(
                '\'', '\"');
        var obj = serializer.Deserialize(new StringReader(json), typeof (Data));
        Console.WriteLine(obj);
        Console.ReadKey();
    }
}
}

这篇关于如何让newtonsoft反序列化yes和no来布尔的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 19:34