joshcomley
joshcomley

Reputation: 28838

Web API custom OData MediaTypeFormatter doesn't honour ModelBuilder information

If I create a custom media type formatter for OData, the serializer ignores my fluent API calls to "ignore" certain properties.

Suppose I have the following OData configuration:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var builder = new ODataConventionModelBuilder();
        var products = builder.EntitySet<Product>("Products");
        products.EntityType.Ignore(e => e.Name); // IGNORE NAME FIELD
        config.EnableQuerySupport();
        config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel());
    }
}

I have specified to ignore the Name property. This all works fine and the Name property is ignored.

If I so much as add the following code to my WebApiConfig class - directly using the default OData serializer/deserializer instances - my Name property is no longer ignored:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var builder = new ODataConventionModelBuilder();
        var products = builder.EntitySet<Product>("Products");
        products.EntityType.Ignore(e => e.Name); // IGNORE NAME FIELD
        config.EnableQuerySupport();

        // INSERT CUSTOM FORMATTERS
        config.Formatters.InsertRange(0,
            ODataMediaTypeFormatters.Create(
            DefaultODataSerializerProvider.Instance,
            DefaultODataDeserializerProvider.Instance));

        config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel());
    }
}

Of course, the same results occur if I implement my own ODataSerializerProvider etc., but for the purposes of example I felt it worth pointing out that this even happens on the default instances.

If I use the following attribute the "ignore" is honoured:

public class Product
{
    public int Id { get; set; }
            [IgnoreDataMember]
    public string Name { get; set; }
}

But firstly I don't like this approach and secondly I can't actually access some of the classes to add the attribute.

Any thoughts?

Upvotes: 1

Views: 1318

Answers (1)

joshcomley
joshcomley

Reputation: 28838

Found the answer.

Instead of:

    config.Formatters.InsertRange(0,
        ODataMediaTypeFormatters.Create(
        DefaultODataSerializerProvider.Instance,
        DefaultODataDeserializerProvider.Instance));

Use:

    config.Formatters.Clear();
    config.Formatters.AddRange(
        ODataMediaTypeFormatters.Create(
        DefaultODataSerializerProvider.Instance,
        DefaultODataDeserializerProvider.Instance));

Upvotes: 3

Related Questions