c# - 在 C# 中如何将属性名称和值列表转换为实例化的类对象
问题描述
我有以下格式的键/值列表
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 会很有用,并且可以通过这种方式转换为对象
解决方案
使用 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);
}
}
}
推荐阅读
- javascript - 如何使文本和图像淡入淡出作为幻灯片显示?
- javascript - 如何在字符串中传递字符串
- asp.net-mvc-4 - 如何调用某些控制器的方法并从查询字符串中传递参数
- video-streaming - 如何通过媒体基础使用英特尔 Quicksync 进行解码?
- excel - Excel VBA 在同一窗口或选项卡中导航
- visual-studio - 更新 SSL 版本后 POCO“未解析的外部符号”链接器错误
- c# - 在 C# 中为任务定义参数化方法
- tensorflow - 客户端中的Tensorflow ServingInputReceiver输入形状错误
- reactjs - React 高阶组件阻塞 props 传播
- selenium - 未捕获的 DOMException:无法在“CommandLineAPI”上执行“$”:不是有效的选择器