Skip to content

Instantly share code, notes, and snippets.

@raghuramn
Created August 15, 2013 00:34
Show Gist options
  • Save raghuramn/6237208 to your computer and use it in GitHub Desktop.
Save raghuramn/6237208 to your computer and use it in GitHub Desktop.
The sample shows how to support named streams with web API OData using some of the extensiblity points in the OData formatter.
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.OData;
using System.Web.Http.OData.Builder;
using System.Web.Http.OData.Formatter;
using System.Web.Http.OData.Formatter.Deserialization;
using System.Web.Http.OData.Formatter.Serialization;
using Microsoft.Data.Edm;
using Microsoft.Data.OData;
namespace NamedStreams
{
class Program
{
static void Main(string[] args)
{
HttpServer server = new HttpServer();
server.Configuration.Routes.MapODataRoute("odata", "odata", GetEdmModel());
server.Configuration.Formatters.InsertRange(0,
ODataMediaTypeFormatters.Create(
new NamedStreamAwareSerializerProvider(), new DefaultODataDeserializerProvider()));
HttpClient client = new HttpClient(server);
PrintResponse("Get photos", client.GetAsync("http://localhost/odata/Photos").Result);
PrintResponse("Get small image", client.GetAsync("http://localhost/odata/Photos(0)/SmallImg").Result);
}
private static void PrintResponse(string title, HttpResponseMessage response)
{
Console.WriteLine(title + "\n");
response.EnsureSuccessStatusCode();
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
Console.WriteLine(new String('*', 80));
}
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Photo>("Photos");
return builder.GetEdmModel();
}
}
public class Photo
{
public Photo()
{
Tags = new List<string>();
}
public int ID { get; set; }
public ICollection<string> Tags { get; set; }
public Stream SmallImg { get; set; }
public Stream MediumImg { get; set; }
public Stream LargeImg { get; set; }
}
public class PhotosController : ODataController
{
public IEnumerable<Photo> GetPhotos()
{
return new Photo[] { new Photo() };
}
public HttpResponseMessage GetSmallImg()
{
return new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("....image stream01010010101001010....")
};
}
}
// custom serializer provider for using custom entity serializer.
public class NamedStreamAwareSerializerProvider : DefaultODataSerializerProvider
{
private NamedStreamAwareEntityTypeSerializer _customEntitySerializer;
public NamedStreamAwareSerializerProvider()
{
_customEntitySerializer = new NamedStreamAwareEntityTypeSerializer(this);
}
public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType)
{
if (edmType.IsEntity())
{
// use our custom entity serializer.
return _customEntitySerializer;
}
return base.GetEdmTypeSerializer(edmType);
}
}
// custom entity type serializer that understands named streams.
public class NamedStreamAwareEntityTypeSerializer : ODataEntityTypeSerializer
{
public NamedStreamAwareEntityTypeSerializer(ODataSerializerProvider serializerProvider)
: base(serializerProvider)
{
}
public override ODataProperty CreateStructuralProperty(IEdmStructuralProperty structuralProperty,
EntityInstanceContext entityInstanceContext)
{
// if it is a named stream.
if (structuralProperty.Type.IsStream())
{
return ToNamedStreamProperty(entityInstanceContext, structuralProperty);
}
return base.CreateStructuralProperty(structuralProperty, entityInstanceContext);
}
private static ODataProperty ToNamedStreamProperty(EntityInstanceContext entity, IEdmStructuralProperty streamProperty)
{
return new ODataProperty
{
Name = streamProperty.Name,
Value = new ODataStreamReferenceValue
{
ContentType = "img/png",
ReadLink = new Uri(entity.GenerateSelfLink(includeCast: false) + "/" + streamProperty.Name)
}
};
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment