C# 向ExpandooObject动态添加嵌套属性

C# 向ExpandooObject动态添加嵌套属性,c#,dynamic,expandoobject,C#,Dynamic,Expandoobject,我得到了一个JSON对象(可能包含多个级别的JSON数组等等),我想将其转换为ExpandooObject 我知道如何在运行时将简单属性添加到ExpandoObject,因为它实现了IDictionary,但如何在运行时添加嵌套属性(例如,myexpando.somelist.anotherlist.someitem),这样可以正确解析 编辑:目前,这适用于简单(一级)属性: var exo = new ExpandoObject() as IDictionary<String, Obje

我得到了一个JSON对象(可能包含多个级别的JSON数组等等),我想将其转换为ExpandooObject

我知道如何在运行时将简单属性添加到ExpandoObject,因为它实现了IDictionary,但如何在运行时添加嵌套属性(例如,
myexpando.somelist.anotherlist.someitem
,这样可以正确解析

编辑:目前,这适用于简单(一级)属性:

var exo = new ExpandoObject() as IDictionary<String, Object>;
exo.Add(name, value);
var exo=new ExpandoObject()作为IDictionary;
外部添加(名称、值);

问题是如何嵌套名称并相应解析ExpandooObject。

这样做怎么样:

var exo = new ExpandoObject() as IDictionary<String, Object>;
var nested1 = new ExpandoObject() as IDictionary<String, Object>;

exo.Add("Nested1", nested1);
nested1.Add("Nested2", "value");

dynamic d = exo;
Console.WriteLine(d.Nested1.Nested2); // Outputs "value"
var exo=new ExpandoObject()作为IDictionary;
var nested1=作为IDictionary的新ExpandooObject();
exo.Add(“嵌套1”,嵌套1);
嵌套1.添加(“嵌套2”,“值”);
动态d=exo;
Console.WriteLine(d.Nested1.Nested2);//输出“值”

当调用
TryGetValue
时,可以通过存储对以前检索到的对象或字典的引用来实现这一点。我使用的类如下所示:

public DynamicFile(IDictionary<string, object> dictionary)
{
    if (dictionary == null)
        throw new ArgumentNullException("dictionary");
    _dictionary = dictionary;
    _lastGetRef = _dictionary;
}

private readonly IDictionary<string, object> _dictionary;
private IDictionary<string, object> _lastGetRef;

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
    if (!_dictionary.TryGetValue(binder.Name, out result))
    {
        result = null;
        return true;
    }

    var dictionary = result as IDictionary<string, object>;
    if (dictionary != null)
    {
        result = new DynamicFile(dictionary);
        _lastGetRef = dictionary;
        return true;
    }

    return true;
}

public override bool TrySetMember(SetMemberBinder binder, object value)
{
    if(_dictionary.ContainsKey(binder.Name))
        _dictionary[binder.Name] = value;
    else if (_lastGetRef.ContainsKey(binder.Name))
        _lastGetRef[binder.Name] = value;
    else
        _lastGetRef.Add(binder.Name, value);

    return true;
}
您可能可以在
TryGetMember
中编写一些代码,在密钥不存在时自动添加字典,但我不需要它,所以我没有添加它。

非常简单

dynamic myexpando = new ExpandoObject();
myexpando.somelist = new ExpandoObject() as dynamic;
myexpando.somelist.anotherlist = new ExpandoObject() as dynamic;
myexpando.somelist.anotherlist.someitem = "Hey Hey There! I'm a nested value :D";
扩展

public static class ObjectExtension
{
    public static ExpandoObject ToExpando(this object source)
    {
        IDictionary<string, object> anonymousDictionary = new RouteValueDictionary(source);

        IDictionary<string, object> expando = new ExpandoObject();

        foreach (var item in anonymousDictionary)
            expando.Add(item);

        return (ExpandoObject)expando;
    }
}
    public IActionResult Client(string username)
    {
        var client = HttpContext.Items["profile"] as Client;

        var model = new
        {
            client.Id,
            client.Name,
            client.Surname,
            client.Username,
            client.Photo,
            CoverPhoto = new {
               client.CoverPhoto.Source,
               client.CoverPhoto.X
            }.ToExpando(),
        }.ToExpando();

        return View(model);
    }
Client.cshtml

<img id="cover-photo" src="@Model.CoverPhoto.Source" />

Alex,考虑到你前面的问题,我认为你需要的是DynamicObject而不是ExpandoObject。See及其应用
<img id="cover-photo" src="@Model.CoverPhoto.Source" />