Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

customizing odata output from asp.net web api

I'm using the new ASP.NET webapi odata (version 4.0.0 last published 27/2/2013 according to Nuget)

Basically I'm doing it as described here: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api

I'm publishing my data transfer objects and the odata atom pub feed is created but I'd like to have some more control over it. Mainly I'd like to be able to do the following:

  • decide what goes on the title, author and updated elements for the feed
  • decide whether or not to have the edit links
  • change what is shown in <category term="X"and in m:type in sub properties that are classes in my application. Currently they expose the c# class names with the full namespace but I don't want to expose this.

Thanks.

like image 705
cellik Avatar asked Feb 28 '13 10:02

cellik


1 Answers

The OData media type formatter is more extensible now. Samples follow.

1) decide what goes on the title, author and updated elements for the feed

public class AtomMetadataFeedSerializer : ODataFeedSerializer
{
    public AtomMetadataFeedSerializer(IEdmCollectionTypeReference edmType, ODataSerializerProvider serializerProvider)
        : base(edmType, serializerProvider)
    {
    }

    public override ODataFeed CreateODataFeed(IEnumerable feedInstance, ODataSerializerContext writeContext)
    {
        ODataFeed feed = base.CreateODataFeed(feedInstance, writeContext);
        feed.Atom().Title = new AtomTextConstruct { Kind = AtomTextConstructKind.Text, Text = "My Awesome Feed" };
        return feed;
    }
}

public class CustomSerializerProvider : DefaultODataSerializerProvider
{
    public override ODataEntrySerializer CreateEdmTypeSerializer(IEdmTypeReference edmType)
    {
        if (edmType.IsCollection() && edmType.AsCollection().ElementType().IsEntity())
        {
            // feed serializer
            return new AtomMetadataFeedSerializer(edmType.AsCollection(), this);
        }

        return base.CreateEdmTypeSerializer(edmType);
    }
}

And register the custom serializer provider using,

config.Formatters.InsertRange(0, ODataMediaTypeFormatters.Create(new CustomSerializerProvider(), new DefaultODataDeserializerProvider()));

2) customize edit links

public class CustomEntityTypeSerializer : ODataEntityTypeSerializer
{
    public CustomEntityTypeSerializer(IEdmEntityTypeReference edmType, ODataSerializerProvider serializerProvider)
        : base(edmType, serializerProvider)
    {
    }

    public override ODataEntry CreateEntry(EntityInstanceContext entityInstanceContext, ODataSerializerContext writeContext)
    {
        ODataEntry entry = base.CreateEntry(entityInstanceContext, writeContext);
        if (notProduceEditLinks)
        {
            entry.EditLink = null;
        }

        return entry;
    }
}

public class CustomSerializerProvider : DefaultODataSerializerProvider
{
    public override ODataEntrySerializer CreateEdmTypeSerializer(IEdmTypeReference edmType)
    {
        if (edmType.IsEntity())
        {
            // entity type serializer
            return new CustomEntityTypeSerializer(edmType.AsEntity(), this);
        }

        return base.CreateEdmTypeSerializer(edmType);
    }
}

and register the custom serializer provider as above.

We still don't support scenario 3 i.e aliasing type names and namespaces.

like image 83
RaghuRam Nadiminti Avatar answered Oct 20 '22 23:10

RaghuRam Nadiminti