1

When I try to send a POST / PUT request using .NET FHIR API to asp.net Web API 2 server, I get the error message:

Hl7.Fhir.Rest.FhirOperationException: the operation failed due to a
client error (UnsupportedMediaType). The body has no content.

1) Do I need to create some kind of MediaType Handler / Formatter?

2) Is there an open source server in which code implements the best practices of the .NET FHIR API?

I looked at Fiddler, seems fhir client sends correct JSON in the body

fhirClient = new FhirClient(serverUrl);
fhirClient.PreferredFormat = ResourceFormat.Json;

Patient patient = new Patient();
//fill patient

    var response = fhirClient.Update(patient);

...
// web api 2 server: WebApiConfig.cs:

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/fhir+json"));

I tried:

[HttpPut]
public void Update([FromBody] Resource resource, string id = null)
{
// updating logic
}

//or
[HttpPut]
public void Update(Resource resource, string id = null)
{
// updating logic
}

but, when I tried

[HttpPut]
public void Update([FromBody] object resource, string id = null)
{

I can see inside "object" a deserialized Patient and use jsonParser to get it back

SUNIL DHAPPADHULE
  • 2,755
  • 17
  • 32
Serg
  • 13
  • 5

4 Answers4

0

seems, I have to write my own Fhir MediaTypeFormatter I googled and found this code:

 public class JsonFhirFormatter : FhirMediaTypeFormatter
    {
        private readonly FhirJsonParser _parser = new FhirJsonParser();
        private readonly FhirJsonSerializer _serializer = new FhirJsonSerializer();

        public JsonFhirFormatter() : base()
        {
            foreach (var mediaType in ContentType.JSON_CONTENT_HEADERS)
                SupportedMediaTypes.Add(new MediaTypeHeaderValue(mediaType));
        }

        public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            base.SetDefaultContentHeaders(type, headers, mediaType);
            headers.ContentType = FhirMediaType.GetMediaTypeHeaderValue(type, ResourceFormat.Json);
        }

        public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            try
            {
                var body = base.ReadBodyFromStream(readStream, content);

                if (typeof(Resource).IsAssignableFrom(type))
                {
                    Resource resource = _parser.Parse<Resource>(body);
                    return Task.FromResult<object>(resource);
                }
                else
                {
                    throw Error.Internal("Cannot read unsupported type {0} from body", type.Name);
                }
            }
            catch (FormatException exception)
            {
                throw Error.BadRequest("Body parsing failed: " + exception.Message);
            }
        }

        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
        {
            using(StreamWriter streamwriter = new StreamWriter(writeStream))
            using (JsonWriter writer = new JsonTextWriter(streamwriter))
            {
                SummaryType summary = requestMessage.RequestSummary();

                if (type == typeof(OperationOutcome))
                {
                    Resource resource = (Resource)value;
                    _serializer.Serialize(resource, writer, summary);
                }
                else if (typeof(Resource).IsAssignableFrom(type))
                {
                    Resource resource = (Resource)value;
                    _serializer.Serialize(resource, writer, summary);
                }
                else if (typeof(FhirResponse).IsAssignableFrom(type))
                {
                    FhirResponse response = (value as FhirResponse);
                    if (response.HasBody)
                    {
                        _serializer.Serialize(response.Resource, writer, summary);
                    }
                }
            }

            return Task.CompletedTask;
        }
    }

and register it in Global.asax

Serg
  • 13
  • 5
0

Indeed, see also here: HL7 FHIR serialisation to json in asp.net web api - that answer is based on the code you found above.

Ewout Kramer
  • 984
  • 6
  • 9
0

There are a few options in this, including the open source fhir-net-web-api project on github. There is a aspnetcore version, and an full framework owin version. Check the sample project in there for how to use them.

0

I was having a very similar issue:

Unhandled Exception: Hl7.Fhir.Rest.FhirOperationException: Operation was unsuccessful because of a client error (UnsupportedMediaType). OperationOutcome: Overall result: FAILURE (1 errors and 0 warnings)

[ERROR] (no details)(further diagnostics: content-types not provided, suported content-types: application/json+fhir, application/fhir+json, application/json, text/json).
   at Hl7.Fhir.Rest.TaskExtensions.WaitResult[T](Task`1 task)

What did the trick for me was setting the preferred format:

_client.PreferredFormat = ResourceFormat.Json;

After that no more error.

My versions:

  <package id="Hl7.Fhir.DSTU2" version="1.9.1.1" targetFramework="net472" />
  <package id="Hl7.Fhir.DSTU2.ElementModel" version="1.9.1.1" targetFramework="net472" />
  <package id="Hl7.Fhir.DSTU2.Serialization" version="1.9.1.1" targetFramework="net472" />
  <package id="Hl7.Fhir.DSTU2.Support" version="1.9.1.1" targetFramework="net472" />
  <package id="Hl7.Fhir.DSTU2.Support.Poco" version="1.9.1.1" targetFramework="net472" />```