【问题标题】:Cast type with Newtonsoft.Json使用 Newtonsoft.Json 进行投射类型
【发布时间】:2016-03-30 09:50:50
【问题描述】:

之前,我使用 IDataContractSurrogate 来序列化我的数据,但它与 CPL(便携式类库)不兼容,所以我现在使用 Newtonsoft。

但是,我必须将 ObservableCollection 类型转换为 List :

myobj [ { id:1, name="test1", value="test_1"}, { id:2, name="test2", value="test_2"}]

myobj ["test1", "test2"],

有可能吗? 我试过这样:

public class ccrUser : DefaultContractResolver { // Newtonsoft.Json.Serialization.IContractResolver

        private bool toSerialise;
        public static readonly ccrUser Instance = new ccrUser(true);

        /// <summary>Constructeur</summary>
        /// <param name="pToSerialise">Indique le sens qui sera utlisé (les API ne donnent pas le même format en GET qu'elles attendent en POST).</param>
        public ccrUser(bool pToSerialise) : base() { toSerialise = pToSerialise; }

        protected override JsonContract CreateContract(Type objectType) {
            var contract = base.CreateContract(objectType);
            if ((toSerialise) && (objectType == typeof(ObservableCollection<tblGroup>))) {
                //contract.Converter = new Newtonsoft.Json.Converters.CustomCreationConverter<string>();
                return base.CreateArrayContract(objectType);
            } else
                return contract;
        }
        protected override List<MemberInfo> GetSerializableMembers(Type objectType) {
            var defaultMembers = base.GetSerializableMembers(objectType);
            if ((toSerialise) && (objectType == typeof(ObservableCollection<tblGroup>))) {
                return defaultMembers;
            } else
                return defaultMembers;
        }


        protected override JsonConverter ResolveContractConverter(Type objectType) {
            if (objectType == typeof(ObservableCollection<tblGroup>)) {
                return null; // pretend converter is not specified
            }
            return base.ResolveContractConverter(objectType);
        }

        /// <summary>JSON value provider that always returns a static value</summary>
        public class StaticValueProvider : IValueProvider {
            private readonly object _staticValue;
            public StaticValueProvider(object staticValue) {  _staticValue = staticValue; }
            public void SetValue(object target, object value) { throw new NotSupportedException(); }
            public object GetValue(object target) { return _staticValue; }
        }

        protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
            JsonProperty property = base.CreateProperty(member, memberSerialization);
            if ((toSerialise) && (property.PropertyType == typeof(ObservableCollection<tblGroup>))) {
            }
            return property;
        }
    }

但找不到解决办法。

问候

【问题讨论】:

  • 你为什么不按原样反序列化myobj,然后在其他属性的getter中做一些事情来返回你需要的东西?或者如果问题是相反的(序列化),那么序列化一些其他属性(进行类型转换)而不是原始属性。
  • 因为名字的冲突。在序列化中要求“组”它是一个字符串数组,反序列化要求“组”它是一个对象数组。

标签: c# json rest serialization json.net


【解决方案1】:

您可以序列化/反序列化另一个属性(另一种类型),而不是在序列化/反序列化过程中进行转换:

// serialize only marked members
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
public class SerializableObject
{
    // original property: not serialized
    public TypeA PropertyA { get; set; }

    [JsonProperty(nameof(PropertyA))]
    public TypeB PropertyB
    {
        get
        {
            // convert PropertyA value to TypeB
            return (TypeB)PropertyA;
        }
        set
        {
            // convert TypeB to TypeA and set PropertyA value
            PropertyA = (TypeA)value;
        }
    }
}

PropertyB(可以是private,如果你喜欢)仅用于将PropertyA值序列化/反序列化为另一种类型。

【讨论】:

  • 这行得通,但我认为它并不漂亮:[DataMember(Name ="groups")] public IEnumerable groupsApi { get { return (_groups!=null)? (从 c in (ObservableCollection)_groups 选择 c.value).ToList():null; } 设置 { _groups = new ObservableCollection(); value.ForEach((a) => { _groups.Add(((Newtonsoft.Json.Linq.JObject)a).ToObject()); }) ; } } 公共 ObservableCollection 组 { 获取 { 返回 _groups; } 设置 { _groups = 值; } }
【解决方案2】:

编译出错,无法将List解析为IEnumerable

    [DataMember(Name ="groups")] 
public List<string> groupsApi { get { return (from c in (ObservableCollection<tblGroup>)_groups select c.value).ToList(); } set { _groups = new ObservableCollection<tblGroup>(value); } } 
public ObservableCollection<tblGroup> groups { get { return _groups; } set { _groups = value; } }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 2012-06-09
    • 1970-01-01
    • 2013-02-10
    • 2013-05-05
    相关资源
    最近更新 更多