代码之家  ›  专栏  ›  技术社区  ›  Maksim Vi.

Asp.Net将字典<string,object>反序列化为对象

  •  2
  • Maksim Vi.  · 技术社区  · 15 年前

    反序列化的最佳方法是什么

    Dictionary<string, object>{
       {"fName", "John"},
       {"lName", "Doe"},
       {"email", "john@doe.net"}
    }
    

    为了这个

    class Member{
       string fName;
       string lName;
       string email;
    }
    
    6 回复  |  直到 15 年前
        1
  •  2
  •   µBio    15 年前

    这并不是真正意义上的序列化,通常是指获取一些磁盘或网络格式的数据(二进制、ASCII、JSON等)并将其加载到运行时对象中。

    但是,如果我理解正确的话,我想你想做的是。。。

    public Member( Dictionary<string,object> dictionary )
    { 
        fName = dictionary["fName"];
        lName = dictionary["lName"];
        email = dictionary["email"];
    }
    
    // usage Member m = new Member( inputDictionary );
    
        2
  •  4
  •   Jeremy    9 年前

    NewtonSoft在中国已经很普遍了ASP.NET这些天的应用程序,如果我需要一个简短而甜蜜的解决方案,这种类型的映射,我可以使用一些这样的代码。当然,如果第三方库还没有出现,那么引入它可能是一种滥用,但有时我们只是使用有效的。而Newtonsoft做到了!

    using Newtonsoft.Json;
    class SerializationTests
    {
        public void DictionarySerializeSample()
        {
    
            var dict = new Dictionary<string, object>
            {
                {"fName", "John"},
                {"lName", "Doe"},
                {"email", "john@doe.net"}
            };
    
            string dictInJson = JsonConvert.SerializeObject(dict);
            var member = JsonConvert.DeserializeObject<Member>(dictInJson);
    
            // use Newtonsoft to write out the object re-serialized
            Console.WriteLine(JsonConvert.SerializeObject(member, Formatting.Indented));
    
        }
    
        public class Member
        {
            public string fName;
            public string lName;
            public string email;
        }
    }
    
        3
  •  2
  •   KeithS    15 年前

    return new Member 
    {
       fName = myDictionary["fName"], 
       lName = myDictionary["lName"], 
       email = myDictionary["email"]
    };
    

    public static T Hydrate<T>(this Dictionary<string, string> theDictionary, 
       T myObject = new T()) where T:new() //default/optional parameter is valid in 4.0 only
    {
    
       //var myObject = myObject ?? new T(); //alternative in 3.5 and previous
    
       foreach(string key in myDictionary.Keys)
       {
          var propInfo = typeof(T).GetProperty(key);
    
          if(propInfo == null) throw new ArgumentException("key does not exist");
          propInfo.SetValue(myObject, theDictionary[key], null);
       }
       return myObject;
    }
    
        4
  •  0
  •   Mitchel Sellers    15 年前

    一种似乎有意义的方法是为此使用一个静态助手函数。

    public static Member Create(Dictionary<string, object inputs)
    {
        Member oNew = new Member();
        oNew.fName = inputs["fName"].ToString();
        // etc
        return oNew;
    }
    
        5
  •  0
  •   CodingGorilla    15 年前

    你也可以使用反射,根据你实际使用的对象,可能会有很多代码,但是会更灵活。这可能不是一个完整的示例,但它可以让您了解总体思路。

    public T InstantiateFromDictionary<T>(Dictionary<string, object> values) where T : new()
    {
       Type t = typeof(T);
       T instance = new T();
       foreach(KeyValuePair<string, object> kvp in values)
       {
            PropertyInfo prop = t.GetProperty(kvp.Key);
            prop.SetValue(instance, kvp.Value, null);
       }
    
       return instance;
    }
    
        6
  •  0
  •   Nikki9696    15 年前

    这不是序列化,而是转换。如果你真的想让它敞篷,那就让它敞篷吧。 Implement TypeConverter .

    using System;
    

    使用系统.集合.通用; 使用系统.Linq; 使用系统文本; 使用系统IO; 使用系统.Xml.Linq; 使用系统诊断; 使用System.Xml.Serialization文件; 使用制度全球化;

    命名空间控制台应用程序1 {

    internal class MemberConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context,
      Type sourceType)
        {
            if (sourceType == typeof(Dictionary<string, object>))
            {
                return true;
            }
            return base.CanConvertFrom(context, sourceType);
        }
    
        public override object ConvertFrom(ITypeDescriptorContext context,
      CultureInfo culture, object value)
        {
            if (value is Dictionary<string, object>)
            {
                Member member = new Member();
                Dictionary<string, object> d = (Dictionary<string, object>)value;
                if (d.ContainsKey("fName")) { member.fName = Convert.ToString(d["fName"]); };
                if (d.ContainsKey("lName")) { member.lName = Convert.ToString(d["lName"]); };
                if (d.ContainsKey("email")) { member.email = Convert.ToString(d["email"]); };
                return member;
            }
            return base.ConvertFrom(context, culture, value);
        }
    
        public override object ConvertTo(ITypeDescriptorContext context,
      CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(Dictionary<string, object>))
            {
                Member member = (Member)value;
                Dictionary<string, object> d = new Dictionary<string, object>();
                d.Add("fName", member.fName);
                d.Add("lName", member.lName);
                d.Add("email", member.email);
                return d;
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
    
    }
    
    [TypeConverter(typeof(MemberConverter))]
    internal class Member
    {
        public string fName;
        public string lName;
        public string email;
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var d = new Dictionary<string, object> {
               {"fName", "John"},
               {"lName", "Doe"},
               {"email", "john@doe.net"}
            };
    
            Member m = (Member)TypeDescriptor.GetConverter(typeof(Member)).ConvertFrom(d);
    
            Debugger.Break();
        }
    }
    

    }