【问题标题】:HL7 FHIR serialisation to json in asp.net web apiHL7 FHIR 序列化为 asp.net web api 中的 json
【发布时间】:2014-01-14 15:52:53
【问题描述】:

我正在使用由 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 对象包还是我应该自己编写?

【问题讨论】:

    标签: asp.net-web-api hl7-fhir datacontractjsonserializer


    【解决方案1】:

    虽然 HL7.Fhir NuGet 包的较新版本(目前处于测试阶段)将携带额外的 [DataContract] 和 [DataMember] 属性,从而防止此类错误,但标准的 .NET DataContract 序列化程序将无法将内存中的 POCO 序列化为正确的 FHIR XML 和 Json 表示。 FHIR 序列化具有关于如何使用 XML 和 json 的特定规则,如果不是不可能的话,使用 DataContract 序列化程序的(有限)可能性进行配置是很困难的。

    但是,也没有必要像您在代码 n-p 中显示的那样为每个调用调用 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 标头。

    【讨论】:

    • 谢谢 Ewout。我仍在使用稳定的 0.9.3 nuget 包,所以缺少一些东西,但这真的很有帮助。您在第三个代码块中发布了 XML sn-p,而不是 JSON 代码块,但我明白了。谢谢:)
    • @Ewout,您可以将[HttpOptions ...] 属性添加到元数据方法中。您不需要添加额外的方法。
    • @Ewout 您创建了自定义类 JsonFhirFormatter。但是如何将此格式化程序附加到控制器的方法(即 Metadata())。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-25
    • 2021-12-31
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多