Move from WCF Data Services to Web API – Part 3
See Part 1 and Part 2. I know in Part 2 I said I was going to look at ExpressionTrees and limit down to a single entity but I wanted to fix the Content Negotiation and add the service document. Both turned out to be simple, once I discovered the Media Type you pass into the ODataMediaTypeFormatter doesn’t do anything.
First I created another method to return back the correct MediaTypeFormatter
private MediaTypeFormatter GetFormatter(Type objType) { var conneg = Configuration.Services.GetContentNegotiator(); var result = conneg.Negotiate(objType, Request, Configuration.Formatters); return result.Formatter; }
Then changed GenerateMetadataResponse to this
protected HttpResponseMessage GenerateMetadataResponse() { var odataMediaTypeFormatter = GetFormatter(typeof (IEdmModel)); var formatter = odataMediaTypeFormatter.GetPerRequestFormatterInstance(typeof (IEdmModel), Request, null); var response = Request.CreateResponse(); response.Content = new ObjectContent(typeof(IEdmModel), GetMetadata(), formatter); return response; }
Now it’s not hard coded to XML but still returns XML. What’s still missing if you just say you want JSON it doesn’t error like WCF Data Services did it will just return XML. I think it should error (add to the list)
This is the bottom part of QueryEntitySet
var response = Request.CreateResponse(); var resultType = typeof(IEnumerable<>).MakeGenericType(query.ElementType); var odataMediaTypeFormatter = GetFormatter(resultType); var formatter = odataMediaTypeFormatter.GetPerRequestFormatterInstance(typeof(IEdmCollectionType), Request, null); response.Content = new ObjectContent(resultType, query, formatter); return response;
Pretty straight forward. I also created the Service Document for the OData. That turned out to be simple.
private HttpResponseMessage GenerateServiceDocument() { var response = Request.CreateResponse(); var odataMediaTypeFormatter = GetFormatter(typeof(ODataWorkspace)); var formatter = odataMediaTypeFormatter.GetPerRequestFormatterInstance(typeof(ODataWorkspace), Request, null); response.Content = new ObjectContent(typeof(ODataWorkspace), GetServiceDocument(), formatter); return response; }
This is ProcessRequest now
protected virtual HttpResponseMessage ProcessRequest() { var pathHandler = Request.GetODataPathHandler(); var metadata = GetMetadata(); var path = pathHandler.Parse(metadata, GetODataPath()); Request.SetODataPath(path); Request.SetODataRouteName("OData"); if (path.Segments.Count == 0) { // Requested service document return GenerateServiceDocument(); } if (path.Segments.Any(s => s.SegmentKind == ODataSegmentKinds.Metadata)) { // Requested metadata return GenerateMetadataResponse(); } var collectionType = path.EdmType as IEdmCollectionType; if (collectionType != null) { // Requested entity collection return QueryEntitySet(collectionType); } return new HttpResponseMessage(HttpStatusCode.NotImplemented); }
Now in Part 4 I’ll get to working on the ExpressionTrees.