Created
September 10, 2013 19:15
-
-
Save raghuramn/6514213 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Net.Http; | |
using System.Net.Http.Headers; | |
using System.ServiceModel; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using System.Web.Http; | |
using System.Web.Http.Controllers; | |
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 System.Web.Http.Routing; | |
using System.Web.Http.SelfHost; | |
using Microsoft.Data.Edm; | |
using Microsoft.Data.OData; | |
namespace RebaseLinks | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); | |
builder.EntitySet<Customer>("Customers"); | |
builder.EntitySet<Order>("Orders"); | |
HttpSelfHostConfiguration config = new HttpSelfHostConfiguration("http://localhost:8080"); | |
config.HostNameComparisonMode = HostNameComparisonMode.Exact; | |
HttpSelfHostServer server = new HttpSelfHostServer(config); | |
server.Configuration.Routes.MapODataRoute("odata", "", builder.GetEdmModel()); | |
var odataFormatters = ODataMediaTypeFormatters.Create(new CustomSerializerProvider(), new DefaultODataDeserializerProvider()); | |
server.Configuration.Formatters.Clear(); | |
server.Configuration.Formatters.InsertRange(0, odataFormatters); | |
// inject the custom message handler that replaces urlhelper. | |
server.Configuration.MessageHandlers.Add(new LinkRewritingMessageHandler()); | |
server.OpenAsync().Wait(); | |
HttpClient client = new HttpClient(); | |
var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost:8080/Customers"); | |
request.Headers.Accept.Add(MediaTypeWithQualityHeaderValue.Parse("application/json;odata=fullmetadata")); | |
var response = client.SendAsync(request).Result; | |
Console.WriteLine(response); | |
Console.WriteLine(response.Content.ReadAsStringAsync().Result); | |
} | |
} | |
public class CustomSerializerProvider : DefaultODataSerializerProvider | |
{ | |
private RebasingFeedSerializer _feedSerializer; | |
public CustomSerializerProvider() | |
{ | |
_feedSerializer = new RebasingFeedSerializer(this); | |
} | |
public override ODataEdmTypeSerializer GetEdmTypeSerializer(IEdmTypeReference edmType) | |
{ | |
// feed | |
if (edmType.IsCollection() && edmType.AsCollection().ElementType().IsEntity()) | |
{ | |
return _feedSerializer; | |
} | |
return base.GetEdmTypeSerializer(edmType); | |
} | |
} | |
// custom feed serializer for rebasing next page links. | |
public class RebasingFeedSerializer : ODataFeedSerializer | |
{ | |
Uri _baseUri = new Uri("http://odata.org"); | |
public RebasingFeedSerializer(ODataSerializerProvider serializerProvider) | |
: base(serializerProvider) | |
{ | |
} | |
public override ODataFeed CreateODataFeed(IEnumerable feedInstance, IEdmCollectionTypeReference feedType, | |
ODataSerializerContext writeContext) | |
{ | |
ODataFeed feed = base.CreateODataFeed(feedInstance, feedType, writeContext); | |
if (feed.NextPageLink != null) | |
{ | |
feed.NextPageLink = new Uri(_baseUri, feed.NextPageLink.PathAndQuery); | |
} | |
return feed; | |
} | |
} | |
// A message handler to inject the custom url helper. | |
public class LinkRewritingMessageHandler : DelegatingHandler | |
{ | |
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) | |
{ | |
HttpResponseMessage response = await base.SendAsync(request, cancellationToken); | |
// replace only for OData requests. | |
if (request.GetEdmModel() != null) | |
{ | |
HttpRequestContext requestContext = request.GetRequestContext(); | |
requestContext.Url = new RewritingUrlHelper(request); | |
} | |
return response; | |
} | |
} | |
// A custom url helper that rewrites links | |
public class RewritingUrlHelper : UrlHelper | |
{ | |
Uri _baseUri = new Uri("http://odata.org"); | |
public RewritingUrlHelper(HttpRequestMessage request) | |
: base(request) | |
{ | |
} | |
// This method is called for each and every link that we generate using OData. | |
public override string Link(string routeName, IDictionary<string, object> routeValues) | |
{ | |
string url = base.Link(routeName, routeValues); | |
// rebase to the baseUri. | |
return new Uri(_baseUri, new Uri(url).PathAndQuery).AbsoluteUri; | |
} | |
} | |
#region Models | |
public class Customer | |
{ | |
public int ID { get; set; } | |
public IEnumerable<Order> Orders { get; set; } | |
} | |
public class Order | |
{ | |
public int ID { get; set; } | |
} | |
public class CustomersController : ODataController | |
{ | |
[Queryable(PageSize = 2)] | |
public IEnumerable<Customer> Get() | |
{ | |
return new[] { new Customer(), new Customer(), new Customer() }; | |
} | |
} | |
#endregion | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment