Get the results of a CosmosDb query as a Raw string (payload of the http response) - azure-cosmosdb

I'm using the .NET API of CosmosDB and I'm getting a hard time trying to figure out how to get the raw result of a CosmosDB query prior to it getting deserialized into a class. Browsing the documentation, all examples I find cast the results to an specific class or to a dynamic. That is:
//This returns a Document, wich actually is a dynamic...
client.ReadDocumentAsync(...)
//This returns an object of type MyClass, wich I supose is casted internally by the API
client.ReadDocumentAsync<MyClass>(...)
What I want to do is to get the original raw JSON payload of the result to inspect it without the overhead of deserializing it to anything else.
Does anybody know if it's possible to get the raw result with the .NET api? If so, how?
In other cases, I need to use the result as an ExpandoObject to treat it dynamically, but I find that the "dynamic" results given by the api are not "expandables" so I'm forced to serialize them and then deserialize again in a recursive form into an ExpandoObject. Furthermore, the result is polluted with _rid, Etag, etc. properties that I don't need on my object. It's quite anoying.
I think it's an unnecesary overhead to serialize and then deserialize again, so maybe the optimus way would be to get the raw JSON result and write a method to deserialize directly to Expando.
Or maybe I'm loosing any point and there's an API to get the results as Expandos. Does anybody know it?

Check out this question that I had earlier:
Converting arbitrary json response to list of "things"
Altough I didn't named it, the API in question was actually DocumentDb, so I think you'll be able to use that code.

Seen some bad advice here, but it is built into the SDK natively.
Document doc = cosmosClient.ReadDocumentAsync(yourDocLink);
string json = doc.ToString();

Related

Kusto's `parse_json` doesn't work on custom dimensions

I'm hoping to be able to analyze structured data stored in a custom dimension of a custom telemetry event emitted to application insights, and getting some weird behavior. It seems like the JSON can't be parsed normally, but if I pass it through strcat it is able to parse the json just fine.
customEvents
| where name == "PbConfigFilterComponentSaved"
| take 1
| project
jsonType=gettype(customDimensions.Json),
parsedType=gettype(parse_json(customDimensions.Json)),
strcatType=gettype(strcat('', customDimensions.Json)),
strcatParsedType=gettype(parse_json(strcat('', customDimensions.Json)))
Result:
jsonType: string
parsedType: string
strcatType: string
strcatParsedType: dictionary
Is there a better approach to getting parse_json to work on this kind of value?
Update
In case it's in any way relevant, here's the value of customDimensions.Json:
{"filterComponentKey":"CatalystAgeRange","typeKey":"TemporalConstraint","uiConfig":{"name":"Age","displayMode":"Age"},"config":{"dateSelector":"pat.BirthDTS"},"disabledForScenes":false,"disabledForFilters":false}
Could you please demonstrate a sample record that isn't parsed correctly?
Speculating (before seeing the data): Have you verified the final paragraph here doesn't apply to your case?
It is somewhat common to have a JSON string describing a property bag in which one of the "slots" is another JSON string. […] In such cases, it is not only necessary to invoke parse_json twice, but also to make sure that in the second call, tostring will be used. Otherwise, the second call to parse_json will simply pass-on the input to the output as-is, because its declared type is dynamic.
The type of customDimensions is dynamic and so accessing a property like customDimensions.json from it will return a string typed as dynamic.
You have to explicitly cast it as string and then parse it:
todynamic(tostring(customDimensions.json)).property
I think the "Notes" section in the documentation is exactly the issue, as mentioned by Yoni L. in the previous answer.

Use trace data as metric in Application Insights

Is it possible to mark data from a trace as being a metric?
E.g. if i have a trace with a JSON message, would I be able to mark a field in the JSON document as a metric.
Does it even make sense doing so, or are there better alternatives? I just want to be able to track/graph and receive alerts on the field in the JSON document.
The closest thing i can think of would be to parse out the metric part of your json document, and actually send it as a metric in your trace call?
string theMessage = whatever;
// .. code to parse apart the message, find the json, and grab metric values
// and put them into a dictionary<string,double>
// and any other string values into a dictionary<string,string>
telemetryClient.TrackTrace( theMessage,
optionalDictionaryOfStringToStringProperties,
optionalDictionaryOfStringToDoubleMetricValues );
there's no "automatic" way to do what you want, having the backend parse out values from a trace that contains json.
However, you could parse those values back out in a query if you're using the analytics portal. the query language there lets you do string manipulations, parsing, json parsing, etc. so if you just need it downstream for some kind of analysis, you don't need to do any of that, just do it in the query.

Alfresco Java backed web-script lookup by cmis:objectId

I am writing my first java-backed webscript for Alfresco community edition. I am implementing document properties / preview service, and I take a parameter which is the cmis:objectId of the document in question. I'm having trouble getting started because I haven't been able to access the document based on the cmis id.
What is the best way to get a document (NodeRef?) based on the cmis:objectId when operating server-side in a web-script controller? I see Jeff Potts' great examples on how to implement web scripts, but the mixing of the Java API and CMIS concepts has me stuck. Should I just use the search service and find the object based on the cmis:objectId property? Any pointers appreciated.
Well, the answer is a little ugly, but hopefully this helps someone...
A good way to look up the NodeRef using an 'opaque' objectId should be to use CMISServices, obtained from the registry in your java backed web script, i.e.
docRef = registry.getCMISService().getLatestVersion(docIdStr, false);
Unfortunately, there's a bug in the Alfresco code (or so it seems to me, admittedly a bit of a newbie). The alfresco CMISServicesImpl.getLatestVersion() uses a getObject() method under the covers. That method takes an objectId String as a parameter, but then strips off the version information at the end (i.e. the ";1.0" part of the objectId) and then checks to see if the remaining string is a valid NodeRef. In doing so, it checks it against this pattern (in NodeRef.java):
private static final Pattern nodeRefPattern = Pattern.compile(".+://.+/.+");
If the validation fails, you get a CMISInvalidArgumentException, with a message that xxxxx "is not an object ID".
So, to make a long story short, when I call the web script using a parameter for the objectId like this:
29ea5a16-12a8-497d-aad3-f43969e8a672;1.0
I get the CMIS exception. But, if I call the method with an objectId parameter that looks like this:
workspace://SpacesStore/29ea5a16-12a8-497d-aad3-f43969e8a672;1.0
... then, the "CMIS" lookup succeeds and I get my desired NodeRef back. Of course, all that the CMIS services are doing under the covers is stripping off the ";1.0" from the object ID, treating it as a NodeRef string, and doing the lookup using that.
In other words, you can't do it the right way in 4.2. The best thing to do is as #Gagravarr says and tweak your own objectId string to turn it into a NodeRef. Hopefully it's fixed in 5.x.

JSON + SOAP - Is DataContract necessary?

Here's my problem.
I'm using SOAP to retrieve information from a third-party web service.
Response time is too high, so I was planning on using JSON instead, at least in a couple of methods.
For this I'm using DataContractJsonSerializer, but I seem to be having some trouble.
For example, in SOAP there's a method called getAvailablePublic with returns an object of type getAvailablePublicResponse.
There's an equivalent for this method in JSON, which also returns a an object of type getAvailablePublicResponse.
In order to deserialize the information I needed to create a couple of data contracts, and here are my concerns:
Do I really need to create a DataContract? Why can't I use getAvailablePublicResponse object from asmx?
The problem is that if I create a DataContract, I need to use a different name other than getAvailablePublicResponse, as I would have two objects with the same name (the one created by me, and the one from SOAP), and this would require making several changes in my solution.
Hope this makes sense.
Thanks.
Can you post your client code that is making the call to the web service? I don't know what you are using now, but I'm a fan of RestSharp for making remote calls and serializing JSON to C# classes. Something like this:
RestClient client = new RestClient("http://some.domain.com/someservice?someparam=yes");
var results = client.Execute<MyGreatDTOClass>(new RestRequest(Method.GET));

Are there options with Json.NET that can have it deserialize inconsistent json types into objects?

An example would be that I am consuming json from an api. The api is not consistent in how it returns the json. Say you have an Author and it has a property of Books[]. The api is unfortunately choosing to return Author.Books (of type Book) in cases when there is only one book. The prefered method would be to return just one Book inside Author.Books[].
Json.NET understandably throws a serialization exception when I try to have it deserialize a chunk of json and it finds "Author":{"Book":{... mixed in with "Author":{"Book":["...
Is there a way around this?
Does this answer your question?
Deserializing JSON when sometimes array and sometimes object
I guess the best would be fix the json through a regex replace before sending to the deserializer. If you put here a full sample of a json provided by the API, and a json accepted, i could make the regex for you.

Resources