Reputation: 15053
Some of my models have custom (user managed) properties. Since they are dynamic I can't include them as properties in my model. So I tried providing the propeties using DynamicObject
:
public class MyModel : DynamicObject
{
public Dictionary<String, Object> CustomFields { get; set; }
...
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (binder.Name.StartWith("CustomField_"))
{
// get the custom field
}
return base.TryGetMember(binder, out result);
}
}
Now using Kendo.Mvc.UI.Fluent.GridBuilder
I'm building my custom attributes like this:
@(Html.Kendo().Grid<object>()
.Columns(columns =>
{
...
foreach (var fieldDef in CustomFieldDefinitions)
{
var columnBuilder = columns.Bound("CustomField_" + fieldDef.Name);
columnBuilder.Title(fieldDef.Name);
}
})
...
The extra columns are shown in the grid, but TryGetMember
is never called.
I also tried implementing GetDynamicMemberNames
. No difference.
Is there any way I can achieve this using an IDynamicMetaObjectProvider
implementation (DynamicObject
)?
Upvotes: 1
Views: 1172
Reputation: 15053
Okay, I figured out what went wrong. I was using ajax binding, and in my controller I was basically doing the following:
[HttpPost]
public ActionResult GetRows([DataSourceRequest]DataSourceRequest request)
{
return Json(GetRows<MyModel>().ToDataSourceResult(request, o => o));
}
Which means it was serializing my models which results in a list of objects that did not include my dynamic members.
I fixed it by mapping all the object members (including the dynamic) into a dictionary:
[HttpPost]
public ActionResult GetRows([DataSourceRequest]DataSourceRequest r)
{
return Json(GetRows<MyModel>().ToDataSourceResult(r, ObjectToDictionary));
}
private Dictionary<String, Object> ObjectToDictionary(Object obj)
{
return Dynamic.GetMemberNames(obj)
.ToDictionary(name => name, name => Dynamic.InvokeGet(obj, name));
}
(Dyanmic
comes from the class library https://github.com/ekonbenefits/dynamitey)
Upvotes: 1