Asp.Net Dynamic Data: Full Scaffolding without DbContext/ObjectContext

556 views Asked by At

We recently started using Dynamic Data templates on our website, by manually scaffolding certain 'tables', using the EnableDynamicData extension method and passing the types of our models on certain GridViews/DetailsViews etc.

This actually works quite nicely and is in production already on a couple of select pages. This method uses only the information in the type itself to create a MetaTable containing all the metadata useful to generate the dynamic fields and filters on a bunch of pages.

I noticed that this scaffolding mechanism is quite limited though, since it does not take relationships with other types into account (understandably so, since there is no contextual information at all).

Now comes the question: is it possible to generate the whole MetaModel from an interface for instance? In our web application, we are not accessing the DbContext directly at all. We exposed our context using the OData protocol (through Wcf Data Services) in another module, and the website requests the info via a new DataSource control we devised to communicate with Wcf Data via urls.

Since we are very new to DynamicData, I couldn't find a way of doing this myself. The very first thing I tried was to create my own MetaModel instance using information from two related types, but I failed at it since there doesn't seem to be a way to manually generate that. Initially, what I wanted is the equivalent of something like this:

gridview.EnableDynamicData(typeof(Device));
gridview.EnableDynamicData(typeof(DeviceType));

There is a one-one relation between Device and DeviceType in our model, and I needed to show fields from both models in the same grid in a page. I immediately noticed that the second call was overriding the first registration because errors popped up. I then took a look at the disassembled code to find out how it actually worked, and it became clear I wouldn't be able to use this method at all.

At this point, I delved a bit on the whole MetaTable/MetaModel classes to find out if I could then create the tables myself. By using MetaTable.CreateTable method, I can easily create a single MetaTable out of a type, but I fail to see how to create the relationships myself still.

The most elegant way seems to be to go all out on the scaffolding mechanism, and register the whole context on the Global.asax. I then realized that I need the whole DbContext type (and instance) to generate the MetaModel.

The whole problem here is responsibility: I don't want to expose the DbContext to the web application at all. It will not access the database. All it has is a url to the data service and the models that are returned by it (in a shared assembly). At the same time, I need the metadata with the relationships to generate the UI seamlessly.

What alternatives do I have to keep things separated here? The website would ideally use the full scaffolding system without having a dependency on the DbContext implementation and connectionstrings etc. I thought about creating an interface to expose the relationships, kind of a 'fake' datacontext, but all the registration methods I looked at, like MetaModel.RegisterContext, test the type passed to them checking if it is either a DataContext or ObjectContext, and also try to create an instance of it (which makes the use of abstract classes impossible too).

By using full scaffolding like this, we also have the advantage of getting default values automatically from the querystring etc, without having to write code like this on every page:

var table = MetaTable.CreateTable(typeof (Device));
var defaultValues = table.GetColumnValuesFromRoute(HttpContext.Current);
gridview.SetMetaTable(table, defaultValues);

Perhaps it would even be possible to create the MetaModel in the server and expose it via a custom Wcf Service? I would then call this service in the web application startup to register the whole thing in a single go or something to that effect.

We are currently using Asp.Net 4 (.Net 4.0) WebForms on the web layer and Entity Framework 5 Code First for the model mapping.

1

There are 1 answers

1
Wizzard On

there us no solution to this unfortunately at the moment you have to load the full meta model to get the relationships. Now not certain if this will help but David Ebbo did a sample see this thread here