【问题标题】:In C# how to convert list of property names and values to an instantiated class object在 C# 中如何将属性名称和值列表转换为实例化的类对象
【发布时间】:2020-11-06 15:03:58
【问题描述】:

我有以下格式的键/值列表

var temp = new Dictionary<string, string>();
temp["Prop1"] = "Test1";
temp["Prop2"] = "Test2";
temp["SubProperty.Sub1"] = "Test3";
temp["SubProperty.Sub2"] = "Test4";
temp["ListData[0].List1"] = "Test5";
temp["ListData[0].List2"] = "Test6";
temp["ListData[1].List1"] = "Test7";
temp["ListData[1].List2"] = "Test8";

有没有一种简单的方法可以将此列表转换为新对象,如下所示。

public class MainClass
{
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public SubClass SubProperty { get; set; }
    public ListClass[] ListData { get; set; }
}

public class ListClass
{
    public string List1 { get; set; }
    public string List2 { get; set; }
}

public class SubClass
{
    public string Sub1 { get; set; }
    public string Sub2 { get; set; }
}

我知道 ASP MVC 会做类似的事情,获取表单名称和值并自动解析为实例化属性。但找不到他们用的东西。任何帮助表示赞赏。希望转换为类甚至 JSON 会很有用,并且可以通过这种方式转换为对象

【问题讨论】:

  • 如果您不只是使用平面字典,而是在 JSON 中表达,您可以将 JSON 反序列化为类。除此之外,查找 System.Reflection,尤其是 PropertyInfo 类。鉴于您要解释temp["ListData[1].List2"] = "Test8" 之类的内容,这将是很多工作
  • 是的。想要避免构建我自己的解释器,以防我不知道的东西已经存在。我无法控制输入数据。干杯
  • @Flydog 所以我的第一个想法是 Newtonsoft 是否可以将字典转换为 json,然后从中得到一个对象.. 遗憾的是,它不是分层字典,而是以自定义方式扁平化的东西..
  • @danhol86 我认为您不会找到以这种确切方式序列化对象的任何东西。你可能不得不开始建设
  • 看我的回答。似乎可以满足我的需要。确实尝试过字典中的newtonsoft,但没有考虑到“。”。无论如何都为寻找而欢呼

标签: c# json asp.net-mvc


【解决方案1】:

使用 ExpandoObjects 创建以下内容,这似乎可以满足我的需要。如果遇到任何其他情况会更新

var temp = new Dictionary<string, string>();
temp["Prop1"] = "Test1";
temp["Prop2"] = "Test2";
temp["SubProperty.Sub1"] = "Test3";
temp["SubProperty.Sub2"] = "Test4";
temp["ListData[0].List1"] = "Test5";
temp["ListData[0].List2"] = "Test6";
temp["ListData[1].List1"] = "Test7";
temp["ListData[1].List2"] = "Test8";
temp["ListData[5].List1"] = "Test9";
temp["ListData[5].List2"] = "Test10";

var justjson = PropertiesToObject.ToJson(temp);
var myobj = PropertiesToObject.ToObject<MainClass>(temp);


public static class PropertiesToObject
{
    public static T ToObject<T>(Dictionary<string, string> dict)
    {
        var json = ToJson(dict);
        return JsonConvert.DeserializeObject<T>(json);
    }

    public static string ToJson(Dictionary<string, string> dict)
    {
        dynamic expando = new ExpandoObject();
        foreach (var item in dict)
        {
            AddProperty(expando, item.Key, item.Value);
        }

        return JsonConvert.SerializeObject(expando);
    }

    private static ExpandoObject SetValueIfListOrNot(ExpandoObject expando,string propertyName, object propertyValue)
    {
        bool isList = propertyName.Contains("[");
        var listName = propertyName.Split('[').FirstOrDefault();
        int listindex = isList ? int.Parse(propertyName.Split('[').LastOrDefault()?.Split(']').FirstOrDefault()) : 0;

        var expandoDict = expando as IDictionary<string, object>;
        if (expandoDict.ContainsKey(listName) == false)
        {
            if (!isList)
            {
                expandoDict.Add(listName, propertyValue);
            }
            else
            {
                var lobj = new dynamic[0];
                expandoDict.Add(listName, lobj);
            }
        }


        var exi = expandoDict[listName];
        if(exi.GetType().IsArray)
        {
            var ma = exi as dynamic[];
            var len = ma.Length;
            if (len < listindex + 1)
            {
                Array.Resize(ref ma, listindex + 1);
                expandoDict[listName] = ma;
            }

            var item = ma[listindex];
            if(item == null)
            {
                ma[listindex] = propertyValue;
            }
            return ma[listindex];
        } else
        {
            return exi as ExpandoObject;
        }
    }

    private static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue)
    {
        var subprops = propertyName.Split('.');
        var propname = subprops.First();

        var rest = string.Join(".", subprops.Skip(1).ToList());
        if (rest == "")
        {
            SetValueIfListOrNot(expando, propname, propertyValue);
        } else
        {
            var expa = SetValueIfListOrNot(expando, propname, new ExpandoObject());
            AddProperty(expa, rest, propertyValue);
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多