CreateODataEntryReader vs. CreateODataFeedReader

Answered CreateODataEntryReader vs. CreateODataFeedReader

  • 2012년 8월 7일 화요일 오후 4:54
     
     

    Hi all;

    I am creating a driver in our reporting engine to support OData. Our customers will then enter their OData urls for the data they want placed in the report. So we have to support any valid query.

    For a given query, how do I know if I should use ODataMessageReader.CreateODataEntryReader or ODataMessageReader.CreateODataFeedReader? Is there a way to determine which one a given url should use? Our customers sure won't know so I can't have them enter a flag for each query.

    ??? - thanks - dave


    Who will win The International Collegiate Programming Championships?

모든 응답

  • 2012년 8월 7일 화요일 오후 5:08
     
     

    These questions are all for selects. We will never do a Create, Update, or Delete. We're just the R in CRUD :)

    Ok, I think what I need to do is first call ODataMessageReader.DetectPayloadKind(). But that leads to two questions:

    First, It returns an IEnumerable - what do I do if there are multiple kinds in the payload?

    Second, I assume I work from the ODataPayloadKind enum. Feed Entry are pretty obvious and both then give me OReaderState.EntryEnd elements (eventually) and that's what I need. But...

    On a select what other Kinds can I get? I'm guessing Property, Value, BinaryValue, & maybe Collection. For these others, how do I read them?

    thanks - dave


    Who will win The International Collegiate Programming Championships?

  • 2012년 8월 7일 화요일 오후 6:08
    중재자
     
     

    Hi,

    A bit of design story (should help you understand):

    - Unfortunately the format is not selfdescriptive enough to be able to easily tell what payload kind it is. So this is a real issue to solve.

    - First of all, vast majority of clients will know what payload kind should be returned for a given query. This is because they construct the query programmatically, so they know what they're asking for. These clients will call the right Read method (or Create method) to begin with. Note that the read methods will fail if the payload doesn't conform to the payload kind the method reads.

    - So it's really only clients which take the query URL as an external parameter which will need to somehow detect what payload kind to use. These clients will call the DetectPayloadKind method.

    - Unfortunately again, the formats are sometimes so ambiguous that even reading the entire payload is not enough to differentiate between particular payload kinds. So it's not possible to return just a single payload kind.

    - ODL should not be in the business of guessing which payload kind is more likely. So the enumeration returned is guaranteed to return all payload kinds possible in the payload. It may return payloads kinds which are not valid though (so it always returns more, never less). It also returns the payload kinds in what should be considered a random order, so the client code should NOT rely on the ordering.

    - Even clients which take external URLs to execute, are likely to know which payload kinds to prefer. This is due to the fact that the client has to do something with the result. So for example if the goal is to "import" such data, the client knows that it expects either a feed or a single entry, but it wouldn't know how to handle a property anyway (for example). Such clients can take the enumeration, reorder it according to their preference and use the first one. Basically we leave the guessing game up to the client in this case.

    - If the client wants to consume every possible payload kind, it can either have some other way to know which payload kind to use (provide a UI to the user to pick from the enumeration, or have some kind of configuration), or it can provide it's own guessing logic if it needs to. But since it's impossible to know for sure in some cases, we leave it up to the client application.

    So to answer your question: You probably know what you will do with the response. So you're likely to "prefer" certain payload kinds. So call the DetectPayloadKind, order the result in the order of your priority of preference and use the one which comes out on top. All the above said, in the vast majority (and it really means 99.9) cases the DetectPayloadKind will return something sensible (so typically just one payload kind), so you're very likely to get it right most of the time.

    To provide a better answer I would have to know what you're going to do with the data returned and/or how/where do you get the URL to run.

    Thanks,


    Vitek Karas [MSFT]

  • 2012년 8월 7일 화요일 오후 7:08
     
     

    We might be able to make assumptions although I can see Feed and Entry both being likely for many cases. Will it generally know between those two types which it is?

    Also, for our use of pulling data in a select, will we get a Property, Value, BinaryValue, and/or Collection? Or maybe the better question is, what are each of those kinds?

    thanks - dave


    Who will win The International Collegiate Programming Championships?

  • 2012년 8월 8일 수요일 오전 10:06
    중재자
     
     답변됨

    It will usually know whether it's Feed or Entry (in ATOM case it will know always, in JSON case, it is very likely to know, but it's not 100%).

    Payload kinds for responses (in a nutshell):

    Feed - collection of entities - http://services.odata.org/OData/OData.svc/Products

    Entry - single entity (the query is known to return exactly one, you can still have queries which return a collection with one entity in it, in which case it's reported as a feed) - http://services.odata.org/OData/OData.svc/Products

    Property - single property on an entity or complex value - http://services.odata.org/OData/OData.svc/Products(1)/Name

    EntityReferenceLink - response to a $links request for a singleton navigation property - http://services.odata.org/OData/OData.svc/Products(1)/$links/Category

    EntityReferenceLinks - response to a $links request for a collection navigation property - http://services.odata.org/OData/OData.svc/Categories(1)/$links/Products

    Value - the raw value of a primitive property represented as text (most primitive types are serialized as text in this case, except for Edm.Binary which will not be reported as Value) - http://services.odata.org/OData/OData.svc/Products(1)/Price/$value

    BinaryValue - binary raw value of a property (typically Edm.Binary property). Can also be reported for any other binary stream (so for example if the service uses media resource and reports a binary content type for it). I don't have a sample URL at hand, but pretty much anything which returns a content type application/octet-stream.

    Collection - collection of primitive or complex values. This is typically a return value of a service operation which returns a collection of primitive or complex values. I don't have a sample payload for this at hand.

    ServiceDocument - the service document of the OData service - http://services.odata.org/OData/OData.svc/

    MetadataDocument - the metadata document of the OData service - http://services.odata.org/OData/OData.svc/$metadata

    Error - error OData payload - The payload returned for example by http://services.odata.org/OData/OData.svc/Products?$filter=Unknown

    Batch - batch response - any success response to the $batch request (can't be done with a simple GET URL, so no sample)

    Parameter - invalid for response payload

    Unsupported - unknown, unrecognized, ...

    In general it's hard to say what "select" will return, since there's no such thing in OData ($select query option is something a bit different than the typical SQL SELECT statement). Typically OData query will return either Feed or Entry, but see the table above :-)

    Thanks,


    Vitek Karas [MSFT]


  • 2012년 8월 8일 수요일 오후 9:19