ASP.NET MVC3 WebGrid Helper and Model Metadata

2.7k views Asked by At

I'm trying to use the WebGrid html helper in ASP.NET MVC 3 to autogenerate the columns according to the information found in the ModelMetadata. For example the code in a view that accepts a list of objects would be:

var grid = new WebGrid(Model);
@grid.GetHtml(columns: ViewData.ModelMetadata.Properties.Single.Properties
               .Select(p => grid.Column(
                       columnName: p.PropertyName,
                       header: p.ShortDisplayName
               )));

This actually works like a charm (I was surprised it was that easy actually). What happens here is that from the properties of the model I use the ShortDisplayName as the column's header.

The problem? I need to apply a default format to all columns. Basically I want to use the Html.Raw extension for all the data that my grid will display. An attempt would be something like that :

var grid = new WebGrid(Model);
@grid.GetHtml(columns: ViewData.ModelMetadata.Properties.Single.Properties
               .Select(p => grid.Column(
                       columnName: p.PropertyName,
                       header: p.ShortDisplayName,
                       format: (item) => Html.Raw(GetPropertyValue(item, p.PropertyName))
               )));

where the method GetPropertyValue would read the value of the property using reflection or whatever (I need to remind here that item is dynamic and its value is actually the object that is being displayed in the current row).

Is there any better way to do this?

Thanks,

Kostas

2

There are 2 answers

0
David Belmont On

Don't know if you still need some help with this question, but I had a problem just like yours and that's what I did to solve it:

  1. I Used a Foreach loop to iterate through the properties
  2. Filled a variable with the name of the property
  3. Formated the column

The code that I got was something like this:

var columns = List<WebGridColumn>();
foreach (var p in ViewData.ModelMetadata.Properties.Single.Properties) {
   String propertyName = p.PropertyName;
   columns.Add(grid.Column(p.PropertyName, p.ShortDisplayName, format: item => Html.Raw(GetPropertyValue(item.Value, propertyName))));
}
@grid.GetHtml(columns: columns.ToArray());

And that's how I get the property's value:

public static object GetPropertyValue(object obj, String propertyName)
{
    if (propertyName.Contains("."))
    {
        int index = propertyName.IndexOf(".");
        object prop = obj.GetType().GetProperty(propertyName.Substring(0, index)).GetValue(obj, null);
        return GetPropertyValue(prop, propertyName.Substring(index + 1));
    }

    return obj.GetType().GetProperty(propertyName).GetValue(obj, null);
}

I really don't know if this is the best way, but it's working pretty good for me.

0
Dmitry Efimenko On

I suggest you looking into MVCContrib Grid project: http://mvccontrib.codeplex.com/wikipage?title=Grid