Search code examples
c#.netodata

How do I create an ODataMessageReader from an HttpWebResponse?


I am using the Microsoft.Data.OData library and basically want to construct a program which grabs a DataTable out of an OData query, construct a database out of it, and insert the records.

Since this needs to be dynamic, service references are not going to work for me.

After two hours of searching and sifting through documentation on MSDN, I have not yet come up with a solution to my question.

My code so far is below and I just need to know if anyone out there has gotten from an HttpWebRequest to an ODataReader or any relevant class that will let me read the results of the query without writing my own parser and how exactly they did it.

public class ODataPuller
{
    private readonly Uri uri;

    public ODataPuller(Uri uri)
    {
        this.uri = uri;
    }

    private async Task<HttpWebResponse> MakeRequestAsync(string filter)
    {
        filter = "?$filter=" + filter;
        Uri target = new Uri(this.uri, filter);

        HttpWebRequest request = HttpWebRequest.CreateHttp(target);
        request.Headers["Accept"] = "application/xml";

        HttpWebResponse response = await request.GetResponseAsync() as HttpWebResponse;
        return response;
    }

    public async Task<DataTable> GetDataTableAsync(string filter)
    {
        HttpWebResponse response = await this.MakeRequestAsync(filter);

        Stream stream = response.GetResponseStream();

        // Turn this stream into something nice
    }
}

Solution

  • When using ODataLib, you need to implement a message interface yourself (where a message represents an HTTP message: stream & headers). When you're reading a response, you'll need to implement IODataResponseMessage, and when you're writing a request, you'll need to implement IODataRequestMessage.

    We have some sample message implementations for HttpWebRequest and HttpWebResponse that you can use here. (I think there might be some compilation issues with these, but they shouldn't be too hard to fix)

    Once you have the message implementation, you'll pass that into either the ODataMessageReader or ODataMessageWriter constructor. E.g.,

    using (var messageReader = new ODataMessageReader(responseMessage, readerSettings, model))
    {
       var feedReader = messageReader.CreateODataFeedReader(entityType, entitySet);
       while (feedReader.Read())
       {
           switch(feedReader.State)
           {
              case ODataReaderState.EntryEnd:
              {
                 ODataEntry entry = (ODataEntry) feedReader.Item;
                 // access entry.Properties, etc.
                 break;
              }
           }
       }
    }
    

    For documentation of using the library, you can check out this summary of using the library as well as my ODataLib blog: http://odata.jenspinney.com