【问题标题】:Asp.Net Deserialize Dictionary<string, object> to an objectAsp.Net 将 Dictionary<string, object> 反序列化为对象
【发布时间】:2010-09-23 20:31:50
【问题描述】:

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

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

到这里

class Member{
   string fName;
   string lName;
   string email;
}

【问题讨论】:

    标签: c# asp.net serialization


    【解决方案1】:

    如今,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;
        }
    }
    

    【讨论】:

      【解决方案2】:

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

      但是,如果我对您的理解正确,我认为您正在尝试做的是......

      public Member( Dictionary<string,object> dictionary )
      { 
          fName = dictionary["fName"];
          lName = dictionary["lName"];
          email = dictionary["email"];
      }
      
      // usage Member m = new Member( inputDictionary );
      

      【讨论】:

      • 我在考虑这个,但我不喜欢硬编码任何值的想法。这就是为什么我要问最好的方法,如果有任何避免这种方法。我只是在寻找这样的东西Member member = (Member)myDictionary;
      • 我会将它放在Member 的构造函数中,该构造函数将字典作为参数。添加到答案...
      • 如果你想避免硬编码的键值,那么我会使用像@KiethS 提供的基于反射的技术
      • @negative:所以项目总是3?或者可能更多?例如 fName、lName、email 和 Address。
      • @KMan,对,会更多,以Member类为例。
      【解决方案3】:

      如果结构是静态的:

      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;
      }
      

      【讨论】:

      • 我认为我的班级一定有问题,因为typeof(T).GetProperty(key) 始终为空,而typeof(T).GetProperties() 为空。同typeof(Member).GetProperties()
      【解决方案4】:

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

      示例代码

      using System;
      

      使用 System.Collections.Generic; 使用 System.Linq; 使用 System.Text; 使用 System.IO; 使用 System.Xml.Linq; 使用 System.Diagnostics; 使用 System.Xml.Serialization; 使用 System.ComponentModel; 使用 System.Globalization;

      命名空间 ConsoleApplication1 {

      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();
          }
      }
      

      }

      【讨论】:

        【解决方案5】:

        一种似乎有意义的方法是为此设置一个静态辅助函数。

        public static Member Create(Dictionary<string, object inputs)
        {
            Member oNew = new Member();
            oNew.fName = inputs["fName"].ToString();
            // etc
            return oNew;
        }
        

        【讨论】:

          【解决方案6】:

          您也可以对此使用反射,这可能是很多代码,具体取决于您实际使用的对象,但它会更加灵活。这可能不是一个完整的示例,但它可以让您大致了解。

          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;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-01-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多