ExpandoObject contains no public properties only in VS2013
-
23-12-2019 - |
Question
I am trying to deserialize my JSON object and pass it as a model to my view. Since I don't know what properties the model will have, I have read that I should use an ExpandoObject.
Here is what I have tried:
public ActionResult Index()
{
var myObj = new object();
List<Dictionary<string, object>> container = new List<Dictionary<string, object>>()
{
new Dictionary<string, object> { { "Text", "Hello world" } }
};
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
myObj = json_serializer.DeserializeObject(json_serializer.Serialize(container));
return View(myObj.ToExpando());
}
And, in the same namespace I have defined this class:
public static class Helpers
{
public static ExpandoObject ToExpando(this object anonymousObject)
{
IDictionary<string, object> anonymousDictionary = new RouteValueDictionary(anonymousObject);
IDictionary<string, object> expando = new ExpandoObject();
foreach (var item in anonymousDictionary)
expando.Add(item);
return (ExpandoObject)expando;
}
}
And, in my view I have this loop:
@foreach (var item in Model)
{
@item.Text
}
When I run, I get this error:
'System.Collections.Generic.KeyValuePair' does not contain a definition for 'Text'
Upon debugging, the Model doesn't seem to have any public properties. When I look deep within the private members, I see the data that I want.
Why aren't these public properties such that I can access them?
Edit: Here you can see the expando object model that is getting passed to my view:
Note: The SyncRoot
property seems to contain my object.
Edit: This is the deserialized object:
Solution 2
The solution for me was to do something like this (using the ExpandoObjectConverter):
var myObj = new object();
List<Dictionary<string, object>> container = new List<Dictionary<string, object>>()
{
new Dictionary<string, object> { { "Text", "Hello world" } }
};
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
var converter = new ExpandoObjectConverter();
var obj = JsonConvert.DeserializeObject<IEnumerable<ExpandoObject>>(json_serializer.Serialize(container), converter);
return View(obj);
However, this doesn't account for deeply nested JSON objects. I can probably create some sort of recursive method.
It's sad that the framework doesn't support such an obvious requirement; unless I am missing something.
OTHER TIPS
Notice that @item
is defined as a System.Collections.Generic.KeyValuePair
based on your error.
These means that you have two properties: Key and Value.
Here are two possible solution:
@foreach (var item in Model.Values)
{
@item.Id
}
or
@foreach (var item in Model)
{
@item.Value.Id
}