5

我正在使用由 Ewout Kramer 创建的 HL7.Fhir nuget包 0.9.3。

我将它与 ASP.NET Web API 捆绑在一起,但不幸的是,内置的 JSON 序列化没有正确生成 JSON。它包含很多这样的:

"<IdentifierElement>k__BackingField"

正如框架所建议的那样,此代码有效......

public HttpResponseMessage GetConformance()
    {
        var conformance = new Conformance();
        var json = FhirSerializer.SerializeResourceToJson(conformance);
        return new HttpResponseMessage{Content = new StringContent(json)};
    }

但这将变得非常重复,并且不遵循 Web API 的“约定”json/xml 序列化方法。

是否有其他可用的 FHIR 对象包,或者我应该自己编写?

4

1 回答 1

10

尽管 HL7.Fhir NuGet 包的较新版本(目前处于测试阶段)将带有额外的 [DataContract] 和 [DataMember] 属性,从而防止此类错误,但标准 .NET DataContract 序列化程序将无法序列化 in-内存 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 ModelTypes:

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();
}

请注意,我们的服务器不使用资源作为控制器中的参数和返回值。资源不允许您捕获重要的元数据(如 id、version-id、上次修改日期等)。通过在我的控制器中使用 ResourceEntry,可以将此数据与资源数据一起传递,并且 WebApi 框架可以将此元数据绑定到适当的 HTTP 标头。

于 2014-01-15T12:09:52.337 回答