I'm using the Fhir-net-api with DSTU2 to parse JSON objects to C# models. Everything works well, except that I can't access the Reason element of the resource type Procedure. As an example, I parse following JSON object to the Procedure model using the FhirParser:
{
"resourceType": "Procedure",
"identifier": [
{
"system": "https://mrd2.melanoma.org.au/fhir",
"value": "100200199664802"
}
],
"subject": { "reference": "Patient/10101000001733" },
"status": "completed",
"category": {
"coding": [
{
"system": "https://mrd2.melanoma.org.au/fhir/RootType",
"code": "3004"
}
],
"text": "Primary Surgery"
},
"bodySite": [
{
"coding": [
{
"system": "http://snomed.info/sct",
"code": "7771000"
}
],
"text": "Left Forearm, Anterior"
}
],
"reasonReference": { "reference": "/Condition/10106000001807" },
"performedDateTime": "1968-03-11",
"report": [ { "reference": "/DiagnosticReport/100200199664828" } ]
}
and the generated object has following entries (excerpt):
Procedure
I can access Report[0].Reference just fine but it won't work with Reason.Reference. Is the data in my JSON object wrong?
I've seen that Reason is of type Hl7.Fhir.Model.Element and Report of type Hl7.Fhir.Model.ResourceReference. Is there a way to change Reason to Hl7.Fhir.Model.ResourceReference and then access the Reference element?
Would be grateful for any hints. Thanks.
Regards,
Trammy
As you noticed, the type of reasonReference is Model.Element, while the type of report is ResourceReference. This difference has its origin in the definition of these elements in the FHIR specification for Procedure, where report is fixed to the type Reference but reason (or rather reason[x]) can either be a CodeableConcept or a Reference.
When elements can be of multiple types (we call this a "choice element", and you can recognize them because their name ends with [x] in the specification), we have created a C# member that is of type Model.Element (the base class for both Reference and CodeableConcept).
Now, depending on the instance you have just parsed or received, the contents of the reason member can be one of both types. So, you'll have to check in your code:
if(Reports[0].reason is ResourceReference)
{
var reference = (ResourceReference)Reports[0].reason;
//handle the case where this is a reference
//doing reference.Reference will now work as expected
}
else if(Reports[0].reason is CodeableConcept)
{
var concept = (CodeableConcept)Reports[0].reason;
//handle the case where this is a codeable concept
}
else
{
// Oops! Should not happen unless the standard has changed
}
Of course, if you are sure you can only receive instances where reason is a ResourceReference, you can do a cast directly:
var myReference = (ResourceReference)Reports[0].Reference;
// myReference.Reference and myReference.Display will now work
Related
After updating the pusher.com libraries for one of my VS WinForms projects, I've noticed that the JSON I'm receiving from pusher.com is not in the correct format anymore (nothing was changed on the server end of things, just the library update in the desktop app / VS project).
Instead of getting this (after the desktop application I'm making receives it, and displays it via MessageBox.Show(...)):
{
"event": "myevent",
"data": {
"message": {
"header": {
"type": "type1",
"printer": "myprinter"
},
"items": {
"1": "Item 1#03#Kg#1#1782.00#1782.00#6002#03"
},
"info": {
"type": "stuff",
"other": "yes"
}
}
},
"channel": "mychannel"
}
I am now getting this
{
event = cashregister,
data = {
"message": {
"header": {
"type":"type1",
"printer":"myprinter"
},
"items": {
"1":"Item 1#03#Kg#1#1782.00#1782.00#6002#03"
},
"info": {
"type":"stuff",
"other":"yes"
}
}
},
channel = mychannel,
user_id =
}
I've never seen this kind of JSON formatting before, and have not been able to find anything by searching on Google or visiting json.org and going through examples.
The usual JsonConvert.DeserializeObject(myJson.event.ToString()); is not working, and it's throwing an exception - Invalid character after parsing property name. Expected ':' but got: =.
How do I parse this? More importantly, is this even a proper JSON format?
The error that I'm seeing is that as soon as I enter something into a Parameter on the UI it disappears.
I am creating Controllers on the fly based on method decorations, so I can't create the XML that drives swagger.json at build-time. As a way around it, I created another controller which inspects the controllers that were added to the runtime and outputs valid swagger.json (or so I think). This works okay with POST, but seems fails peculiarly when trying to add route parameters to GET.
This is the json I generate for my GET:
"openapi": "3.0.1",
... // cutting out unrelated other stuff
"/api/v1/test4/{Value2}": {
"get": {
"tags": [
],
"summary": "A sample GET",
"parameters": [
{
"name": "Value2",
"in ": "path",
"required": true,
"schema": {
"type": "string",
"format": ""
}
},
,
],
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"$ref": "#/components/schemas/TestReply"
}
}
}
}
}
}
}
The project is a .Net Framework 4.8 one, and the packages I'm using are Microsoft.AspNetCore 2.2.0 and Swashbuckle.AspNetCore 5.5.1.
There's an extra space in the name of the in attribute:
"in ": "path",
^
^
Remove that space.
You can also use https://editor.swagger.io to check your API definition for syntax errors.
With this code:
var button = Value.ForStruct(new Struct{
Fields={
["type"] = Value.ForString("postback"),
["title"] = Value.ForString("Call Representative"),
["payload"] = Value.ForString("+15105551234"),
}
});
var inPayload = Value.ForStruct(new Struct{
Fields ={
["buttons"] = Value.ForList(button),
["text"] = Value.ForString("try the postback"),
["template_type"] = Value.ForString("button"),
}
});
var attachment = Value.ForStruct(new Struct{
Fields ={
["payload"] = inPayload,
["type"] = Value.ForString("template"),
}
});
var msg = Value.ForStruct(new Struct{
Fields ={
["attachment"] = attachment,
});
Payload = new Struct{
Fields ={
["facebook"] = msg
}
I was able to create the following json:
"payload": {
"facebook": {"attachment": {
"payload": {
"buttons": [ {
"type": "postback",
"title": "Call Representative",
"payload": "+15105551234"
}],
"text": "try the postback",
"template_type": "button"
},
"type": "template"
}}
Now I need to create the following other format but I dont find how to do it:
"payload": {
"message": "Yes I did it"
"platform": "kommunicate",
"attachment": {
"payload": {
"buttons": [ {
"type": "postback",
"title": "Call Representative",
"payload": "+15105551234"
}],
"text": "try the postback",
"template_type": "button"
},
"type": "template"
}
I really dont find how to eliminate the first "facebook": { element and leave only:
{
"message": "Yes I did it",
"platform": "kommunicate",
"attachment":
And include message and platform at the same level. Here is the complete json I will like to generate:
"payload": {
"platform": "kommunicate",
"message": "Yes I did it",
"attachment": {
"payload": {
"buttons": [ {
"type": "postback",
"title": "Call Representative",
"payload": "+15105551234"
}],
"text": "try the postbackggggggg",
"template_type": "button"
},
"type": "template"
}
If you want to take an object and convert it to json I would recommend taking a look at Newtonsoft Json.Net library. They have plenty of examples that might help you. There is also protobuf.net library for serializing to protobuf instead of json.
Both libraries are used in similar ways, you create a class with appropriate properties and set the values you want. You will need multiple classes for nested types as in your example. Protobuf requires you to annotate the properties with attributes, while this is optional for json.net. You then send the object to the serialization library and get a string or binary data representing your object. This kind of object is often called a Data Transfer Object (DTO), since the only purpose it has is to aid in serialization or/and transfering the data to another system.
I am using Avro schema to dynamically produce message to a Kafka cluster from a C# application, using the Confluent Kafka client. The data types are not known on compile time so I am using the GenericRecord class from the Avro.Generic namespace, as described here: https://www.confluent.io/blog/decoupling-systems-with-apache-kafka-schema-registry-and-avro/.
I however have an issue - if the schema has a field that can contain null value, it is still required to add the field to the GenericRecord by using the Add method, giving null as value. My application is not aware of the fields that can be null and I don't think it should be - because that would defy the purpose of nullable fields in the schema.
Avro schema:
{
"namespace": "Test",
"type": "record",
"doc": "Test bool type",
"name": "BoolType",
"version": "1",
"fields": [
{
"name": "Data",
"type": [ "null", "boolean" ],
"default": null
},
{
"name": "Source",
"type": "string"
}
]
}
C# code:
var valueRecord = new GenericRecord( valueAvroSchema );
valueRecord.Add( "Data", null );
valueRecord.Add( "Source", "Test app .NET" );
var messageToSend = new Message<GenericRecord, GenericRecord>
{
Key = keyRecord,
Value = valueRecord
};
await _producer.ProduceAsync( _topicName, messageToSend );
If the line:
valueRecord.Add( "Data", null );
is not present, the ProduceAsync method throws a Confluent.Kafka.ProduceException, as seen in the screenshot below.
Is there any way I can automatically populate the fields that can be null in the GenericRecord? The same would apply if I would have to populate the fields with their default value.
Is there any way of doing this in a standard way or do I need to write my own code to read the schema and if there are any nullable fields that are not already set by my application to add them at the end, before publishing?
Thank you!
Avro defaults are only relevant to consumers. The producer must always set each field
I am working on developing a web service which is used to Handling Requests Sent by Alexa and respond back with specific response in .net framework. The request body sent by Alexa to your service in JSON format like below :
{
"version": "string",
"session": {
"new": true,
"sessionId": "string",
"application": {
"applicationId": "string"
},
"attributes": {
"string": {}
},
"user": {
"userId": "string",
"accessToken": "string"
}
},
"context": {
"System": {
"application": {
"applicationId": "string"
},
"user": {
"userId": "string",
"accessToken": "string"
},
"device": {
"supportedInterfaces": {
"AudioPlayer": {}
}
}
},
"AudioPlayer": {
"token": "string",
"offsetInMilliseconds": 0,
"playerActivity": "string"
}
},
"request": {}
}
and Response Body Syntax in Json format below:
{
"version": "string",
"sessionAttributes": {
"string": object
},
"response": {
"outputSpeech": {
"type": "string",
"text": "string",
"ssml": "string"
},
"card": {
"type": "string",
"title": "string",
"content": "string",
"text": "string",
"image": {
"smallImageUrl": "string",
"largeImageUrl": "string"
}
},
"reprompt": {
"outputSpeech": {
"type": "string",
"text": "string",
"ssml": "string"
}
},
"directives": [
{
"type": "string",
"playBehavior": "string",
"audioItem": {
"stream": {
"token": "string",
"url": "string",
"offsetInMilliseconds": 0
}
}
}
],
"shouldEndSession": boolean
}
}
I researched on Amazon Developer Forum Hosting a Custom Skill as a Web Service , Handling Requests Sent by Alexabut i am not able to achieve this thing and one thing i am not using Lambda function i want to make a custom skill and my location is not in North US.
I got the Lib. from github here and used in my web service but not able to sync with this library, anyone here to give me a direction how can i do this or how can i started thanks in advance.
I've just published a project that uses the same AlexaSkillsKit.NET package that you mention. The goal is to help everyone create Alexa Custom Skills using .NET + Visual Studio that you can easily deploy to Azure.
https://github.com/tamhinsf/Azure4Alexa
There's a sample skill implementation that you can use as a pattern for your own Custom Skill. It makes use of httpClient and the usual async patterns.
Just download and fire up Visual Studio to get started!
It's been some time that the last answer was written, plus the example which Azure4Alexa sample implements, uses deprecated base classes, for cases where you might want to use the 'context' part of your Alexa request, you would want to implement SpeechletBase, ISpeechWithContext in your final Speechlet class.
To be honest, I know the README.md on AlexaSkillsKit.net is very dense, but if you do give it some time, and go through the AlexaSkillsKit.Sample project, and go through the definitions of the implemented base classes, you will understand the request handling through and through.
Let me also take this opportunity to breakdown how I understand the classes and their structures:
SampleSessionSpeechlet Class - Is just the final class that Logs your request, and implements the ISpecchletWithContext(which mandates the implementation of OnSessionStarted(), OnLaunch(), OnIntent() & OnSessionEnded()) these four functions are basically handlers of all the requests that Alexa can send to your Web Service.
SpecchletBase Class - Basically Wraps around the SpeechletService Class which actually does the all heavy lifting.
SpeechletService Class - You basically call its GetResponseAsync()(which the SpeechletSerive's GetResponse() wraps) which takes the passed Alexa Request, parses it into a cute little dataClass called SpeechletRequestEnvelope, does session management, passes the SpeechletRequestEnvelope to your your implementation of the OnSessionStarted(), OnLaunch(), OnIntent() or OnSessionEnded() methods, gets your returned objects and Returns your Alexa Response as a class called the SpeechletResponseEnvelope
Hope that helps with some quick implementation, but I highly recommend going through the Lib directory and understand how things work. And who knows? Contribute!