Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent ODataConventionModelBuilder to automatically expose all derived types' metadata?

I'm using ODataConventionModelBuilder to build Edm Model for Web API OData Service like this:

ODataModelBuilder builder = new ODataConventionModelBuilder();

builder.Namespace = "X";

builder.ContainerName = "Y";

builder.EntitySet<Z>("Z");

IEdmModel edmModel = builder.GetEdmModel();

Class Z is located in one assembly, and there is public class Q derived from Z located in different assembly.

The ODataConventionModelBuilder will generates Edm Model that includes definition of class Q (among other derived classes) and it will be exposed with service metadata. That is undesirable in our case.

When derived class in inaccessible (e.g. defined as internal) such problem, sure, doesn't exist.

Is there way to force the ODataConventionModelBuilder to do NOT automatically expose all derived types' metadata?

like image 242
Eugene D. Gubenkov Avatar asked Oct 08 '14 13:10

Eugene D. Gubenkov


2 Answers

This should work:

ODataConventionModelBuilder builder = new ODataConventionModelBuilder();

builder.Namespace = "X";

builder.ContainerName = "Y";

builder.EntitySet("Z");

builder.Ignore<Q>();

IEdmModel edmModel = builder.GetEdmModel();
like image 165
Yi Ding - MSFT Avatar answered Oct 17 '22 21:10

Yi Ding - MSFT


There is no way of disabling the automatic discovery and this is by design. See here.

However, there's a workaround. You have to explicitly Ignore each derived type and then proceed on manually mapping each derived type. Here's a nice loop to ignore the derived types:

var builder = new ODataConventionModelBuilder();
builder.Namespace = "X";
builder.ContainerName = "Y";
builder.EntitySet<Z>("Z");

var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(a => a.GetTypes())
    .Where(t => t.IsSubclassOf(typeof(Z)));

foreach (var type in types)
    builder.Ignore(types.ToArray());

//additional mapping of derived types if needed here

var edmModel = builder.GetEdmModel();

See my blog post for more details.

like image 32
Jerther Avatar answered Oct 17 '22 23:10

Jerther