Using ODataLib to Call WCF and JSON Data Services

I searched around the world and could not find any good samples or tutorials on how to call utility operations using ODataLib. I saw a few who tell me how to get entities and entities, and this is great, but for invoking a maintenance operation.

I am pretty sure that I need to use something other than an ODataEntry , ODataFeed or ODataNavigationLink . I opened the library in JustDecompile and see classes like ODataAction and ODataFunction , but I can’t figure out how to use them.

My needs are pretty simple: I need to call WCF Data Services 5.0, and I need to do this using JSON.

I also know that the upcoming release of the WCF Data Services Client library will support JSON, but unfortunately I need to do this as yesterday. In addition, out of desperation, I even tried to implement the RC version (sigh) using the Mark Stafford JSON light sample , but did not really understand how it works.

Any help or direction would be WELCOMEED! (Especially if it appears on your screen, Mark!)

Thanks! J

0
source share
2 answers

The choice between ODataLib and WCF data services (which depends on ODataLib) as a client often comes down to control. If your use case is simple and you need the most common features, WCF DS is probably right. If you need advanced functionality or precise control over reading the payload, ODataLib is best suited. Everything that said, Vitek already covered conceptually how you will read the operation using ODataLib.

WCF DS will make reading JSON Light easier in version 5.1. This week I will talk about this blog, but the sample you are linking to is what you need to do for this RC. In the example I compiled, there is only one new call - the call to context.Format.UseJson(Func<Uri,ModelResolverResult>) . Let's talk about why this call is necessary in the first place. OData (at least in the Microsoft world) plays great with strong typing. $metadata is a good OData example that describes the data model it works with. Using the Atom payload or even the JSON Verbose payload, most of this type of information has been ported to the payload. With JSON Light, the goal was to strip as much of this metadata from the transport payloads as possible.

If metadata is not available in the band, it should be available out of range. This is the basic requirement behind the signature of the UseJson call. Essentially, whenever WCF DS needs metadata, it will look for a model for a given URI. If he can’t find this model, it ultimately collects the metadata in full. We want to preempt this because it inflates the payload. We can preempt it by telling WCF DS how to resolve the model ahead of schedule. This is what most sampling does.

Walking through the pattern logically (yes, I know that there are a number of other optimizations that could be made - the pattern was mostly optimized for readability):

  • If the model has not been resolved in the past
    • Build a new XmlReader to call EdmxReader.TryParse
    • What are some values ​​for out parameters in EdmxReader.TryParse
    • Call EdmxReader.TryParse
      • If the call succeeds, cache the processed model in the local dictionary (parsing is an expensive operation right now)
      • If the call fails, combine the errors and throw
  • Take the correct model from the cached models and return it to the ModelResolverResult wrapper

Hope this makes sense. If this is not the case, I would like to know why I can make the blog post understandable. And remember that this will be greatly simplified by the time these bits are put into production.

+2
source

ODataLib does not know (and should not know) that it is reading the response of a service operation. The only thing that matters is what kind of payload you want to read.

It depends on what the service operation returns. If it returns a single record, use ODataLib in the same way as reading unidirectional payloads (e.g. ~ / Products (0)), since the wire format will be the same. If the service operation returns a collection of objects, read it as a feed.

If the service operation returns a single primitive or complex value, you can use ODataMessageReader.ReadProperty. I know that the method name is a little misleading, but again because the property payload (e.g. ~ / Products (0) / Name) and the maintenance operation returning a primitive or complex type use the same payload format . In this case, you should ignore the name of the returned property (this is probably the name of the service operation).

If the service operation returns a collection of primitive or complex values, you can use ODataMessageReader.CreateODataCollectionReader. This will return the ODataCollectionReader reader, which you use in a very similar way to the ODataReader. The interesting things that he presents are the elements of the collection in question (the API in this case is pretty easy to understand).

It doesn’t matter if you need to read ATOM or JSON, what is up to you, the API is the same.

+2
source

Source: https://habr.com/ru/post/947088/


All Articles