使用字典中的 DataContract 创建 .NET 对象

Create .NET object with DataContract from a dictionary

定义了 class:

[DataContract]
public class Command
{
        [DataMember(Name = "cmdName")]
        public string CommandName { get; set; }

        [DataMember(Name = "cmdTransactionId")]
        public string CommandTransactionId { get; set; }
}

我想从字典中创建 class 的实例:

Dictionary<string, object> propertyBag = new Dictionary<string, object>();
propertyBag["cmdName"] = "cmd1";
propertyBag["cmdTransactionId"] = "1";
Command command = deserializer.Create<Command>(propertyBag);

DataContractSerializer 不适合我,JavaScriptSerializer.ConvertToType 也不适合我,因为他们每个人都缺少一块阻止我一次性创建对象。

也许你可以试试这个代码 deserializer.Create<Command>(propertyBag):

public T Create<T>(IDictionary<string, object> propertyBag)
{
    var result = (T)FormatterServices.GetUninitializedObject(typeof(T));

    foreach (var item in from member in typeof(T).GetMembers()
                         let dataMemberAttr = member.GetCustomAttributes(typeof(DataMemberAttribute), true).Cast<DataMemberAttribute>().SingleOrDefault()
                         where dataMemberAttr != null && propertyBag.ContainsKey(dataMemberAttr.Name)
                         select new { Member = member, Value = propertyBag[dataMemberAttr.Name] })
    {
        var property = item.Member as PropertyInfo;
        if (property != null)
        {
            property.SetValue(result, item.Value, null);
            continue;
        }

        var field = item.Member as FieldInfo;
        if (field != null)
        {
            field.SetValue(result, item.Value);
            continue;
        }
    }

    return result;
}

此代码未经测试 - 只是在此处输入。

JavaScriptSerializer 将在此处进行一些更改:

var propertyBag = new Dictionary<string, object>();
propertyBag["CommandName"] = "cmd1";
propertyBag["CommandTransactionId"] = "1";

var serializer = new JavaScriptSerializer();
var res = serializer.Serialize(propertyBag);

var command = serializer.Deserialize<Command>(res);

我使用了 Deserialize 方法而不是 ConvertToType 方法。第二个区别更为显着。我使用的字典包含与 Command class 中的属性名称相同的键。如果您不喜欢它,您应该尝试编写自定义 JavaScriptConverter。看到这个 question.