Хотя более новая версия пакета HL7.Fhir NuGet (в настоящее время находится в стадии бета-тестирования) будет содержать дополнительные атрибуты [DataContract] и [DataMember] и, таким образом, предотвратит подобные ошибки, стандартный сериализатор .NET DataContract не сможет сериализовать памяти POCO в правильное представление FHIR XML и Json. Сериализация FHIR имеет определенные правила использования как XML, так и json, которые трудно, если вообще возможно, настроить с использованием (ограниченных) возможностей сериализатора DataContract.
Однако также нет необходимости вызывать FhirSerializer для каждого вызова, как вы показали в своем фрагменте кода (фактически, это будет анти-шаблон WebApi). Например, наш сервер FHIR (по адресу http://spark.furore.com/fhir) основан на WebApi и использует для этого собственный MediaTypeFormatter. Чтобы получить представление о том, как это выглядит, мы создали два средства форматирования, одно для json и одно для xml:
public class JsonFhirFormatter : MediaTypeFormatter
{
public JsonFhirFormatter() : base()
{
foreach (var mediaType in ContentType.JSON_CONTENT_HEADERS)
SupportedMediaTypes.Add(new MediaTypeHeaderValue(mediaType));
}
}
Это сообщает фреймворку, что форматтер примет любой из форматов в ContentType.JSON_CONTENT_HEADERS (которые представляют собой application/json и некоторые распространенные варианты) и сможет анализировать и читать типы моделей FHIR:
public override bool CanReadType(Type type)
{
return type == typeof(ResourceEntry) || type == typeof(Bundle) || (type == typeof(TagList));
}
public override bool CanWriteType(Type type)
{
return type == typeof(ResourceEntry) || type == typeof(Bundle) || (type == typeof(TagList)) || type == typeof(OperationOutcome);
}
Наконец, вы должны переопределить методы ReadFromStreamAsync и WriteToStreamAsync:
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
// Some code left out...
XmlWriter writer = new XmlTextWriter(writeStream, Encoding.UTF8);
if (type == typeof(ResourceEntry))
{
ResourceEntry entry = (ResourceEntry)value;
FhirSerializer.SerializeResource(entry.Resource, writer);
content.Headers.SetFhirTags(entry.Tags);
}
Теперь, когда вы это сделали, ваш контроллер может просто сделать:
[HttpGet, Route("metadata")]
public ResourceEntry Metadata()
{
return service.Conformance();
}
[HttpOptions, Route("")]
public ResourceEntry Options()
{
return service.Conformance();
}
Обратите внимание, что наш сервер не использует ресурсы в качестве параметров и возвращаемых значений в контроллере. Ресурсы не позволят вам получить важные метаданные (например, идентификатор, идентификатор версии, дату последнего изменения и т. д.). Используя ResourceEntry в моем контроллере, эти данные можно передавать вместе с данными ресурсов, а платформа WebApi может связать эти метаданные с соответствующими заголовками HTTP.
person
Ewout Kramer
schedule
15.01.2014