in src/Microsoft.Health.Fhir.Shared.Api/Features/Formatters/FhirJsonOutputFormatter.cs [70:167]
public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
{
EnsureArg.IsNotNull(context, nameof(context));
EnsureArg.IsNotNull(selectedEncoding, nameof(selectedEncoding));
context.HttpContext.AllowSynchronousIO();
HttpResponse response = context.HttpContext.Response;
var elementsSearchParameter = context.HttpContext.GetElementsOrDefault();
var summarySearchParameter = context.HttpContext.GetSummaryTypeOrDefault();
var pretty = context.HttpContext.GetPrettyOrDefault();
var hasElements = elementsSearchParameter?.Any() == true;
Resource resource = null;
var summaryProvider = _modelInfoProvider.StructureDefinitionSummaryProvider;
var additionalElements = new HashSet<string>();
if (context.Object is Hl7.Fhir.Model.Bundle)
{
var bundle = context.Object as Hl7.Fhir.Model.Bundle;
resource = bundle;
if (hasElements ||
summarySearchParameter != Hl7.Fhir.Rest.SummaryType.False ||
!bundle.Entry.All(x => x is RawBundleEntryComponent))
{
// _elements is not supported for a raw resource, revert to using FhirJsonSerializer
foreach (var rawBundleEntryComponent in bundle.Entry)
{
if (rawBundleEntryComponent is RawBundleEntryComponent)
{
rawBundleEntryComponent.Resource = ((RawBundleEntryComponent)rawBundleEntryComponent).ResourceElement.ToPoco<Resource>(_deserializer);
if (hasElements)
{
var typeinfo = summaryProvider.Provide(rawBundleEntryComponent.Resource.TypeName);
var required = typeinfo.GetElements().Where(e => e.IsRequired).ToList();
additionalElements.UnionWith(required.Select(x => x.ElementName));
}
}
}
}
else
{
await _bundleSerializer.Serialize(context.Object as Hl7.Fhir.Model.Bundle, context.HttpContext.Response.Body, pretty);
return;
}
}
else if (context.Object is RawResourceElement)
{
if (hasElements ||
summarySearchParameter != Hl7.Fhir.Rest.SummaryType.False)
{
// _elements is not supported for a raw resource, revert to using FhirJsonSerializer
resource = (context.Object as RawResourceElement).ToPoco<Resource>(_deserializer);
if (hasElements)
{
var typeinfo = summaryProvider.Provide(resource.TypeName);
var required = typeinfo.GetElements().Where(e => e.IsRequired).ToList();
additionalElements.UnionWith(required.Select(x => x.ElementName));
}
}
else
{
await (context.Object as RawResourceElement).SerializeToStreamAsUtf8Json(context.HttpContext.Response.Body);
return;
}
}
else
{
resource = (Resource)context.Object;
if (hasElements)
{
var typeinfo = summaryProvider.Provide(resource.TypeName);
var required = typeinfo.GetElements().Where(e => e.IsRequired).ToList();
additionalElements.UnionWith(required.Select(x => x.ElementName));
}
}
if (hasElements)
{
additionalElements.UnionWith(elementsSearchParameter);
additionalElements.Add("meta");
}
using (TextWriter textWriter = context.WriterFactory(response.Body, selectedEncoding))
using (var jsonWriter = new JsonTextWriter(textWriter))
{
jsonWriter.ArrayPool = _charPool;
if (pretty)
{
jsonWriter.Formatting = Formatting.Indented;
}
_fhirJsonSerializer.Serialize(resource, jsonWriter, summarySearchParameter, hasElements ? additionalElements.ToArray() : null);
await jsonWriter.FlushAsync();
}
}