问题描述
我正在使用Ewout创建的HL7.Fhir 程序包0.9.3 Kramer。
I'm using the HL7.Fhir nuget package 0.9.3 created by Ewout Kramer.
我将它与ASP.NET Web API绑定在一起,但是不幸的是,内置的JSON序列化无法正确生成JSON。它包含许多内容:
I am tying it up with ASP.NET Web API, but unfortunately the built in JSON serialization isn't generating the JSON correctly. It contains lots of this:
"<IdentifierElement>k__BackingField"
如框架所建议,此代码有效...
As suggested by the framework, this code works...
public HttpResponseMessage GetConformance()
{
var conformance = new Conformance();
var json = FhirSerializer.SerializeResourceToJson(conformance);
return new HttpResponseMessage{Content = new StringContent(json)};
}
但这将变得非常重复,并且不会遵循按惯例 Web API的json / xml序列化方法。
but this will become quite repetitive and isn't following the "by convention" json/xml serialization methods of Web API.
还有其他可用的FHIR对象包吗?还是我应该自己编写?
Are there any other FHIR objects packages available or should I just write my own?
推荐答案
尽管较新版本的HL7.Fhir NuGet软件包(当前处于beta版)将带有附加的[DataContract]和[DataMember]属性,从而防止了此类错误,则标准.NET DataContract序列化程序将无法将内存POCO序列化为正确的FHIR XML和Json表示形式。 FHIR序列化具有有关如何同时使用XML和json的特定规则,要使用DataContract序列化器的(有限)可能性进行配置,即使不是不可能,也很难做到。
Although the newer version of the HL7.Fhir NuGet package (currently in beta) will carry additional [DataContract] and [DataMember] attributes, and thus prevent these kind of errors, the standard .NET DataContract serializer will not be able to serialize in-memory POCO's to the correct FHIR XML and Json representation. The FHIR serialization has specific rules about how both XML and json are used, which is hard, if not impossible, to configure using the (limited) possibilities of the DataContract serializer.
但是,也不必为代码段中显示的每个调用调用FhirSerializer(实际上,这是WebApi的反模式)。例如,我们的FHIR服务器(位于)基于WebApi并使用自定义MediaTypeFormatter来处理此问题。为了了解外观,我们创建了两个格式化程序,一个用于json,一个用于xml:
However, it's also not necessary to invoke the FhirSerializer for each call as you showed in your codesnippet (in fact, that would be an WebApi anti-pattern). For example, our FHIR server (at http://spark.furore.com/fhir) is based on WebApi and uses a custom MediaTypeFormatter to handle this. To get a taste of what that looks like, we have created two formatters, one for json and one for 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中的格式(它们是应用程序/ json和一些常见变体),并且能够解析和读取FHIR ModelType:
This tells the framework this formatter will take any of the formats in ContentType.JSON_CONTENT_HEADERS (which are application/json and some common variants) and is able to parse and read 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方法:
Finally, you have to override the ReadFromStreamAsync and WriteToStreamAsync methods:
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);
}
现在,一旦完成此操作,您的控制器就可以做到: / p>
Now, once you've done that, your Controller can simply do:
[HttpGet, Route("metadata")]
public ResourceEntry Metadata()
{
return service.Conformance();
}
[HttpOptions, Route("")]
public ResourceEntry Options()
{
return service.Conformance();
}
请注意,我们的服务器不使用Resources作为参数,也不在控制器中返回值。资源不允许您捕获重要的元数据(例如ID,版本ID,上次修改日期等)。通过在控制器中使用ResourceEntry,可以将这些数据与资源数据一起传递,并且WebApi框架可以将此元数据绑定到适当的HTTP标头。
Note that our server does not use Resources as parameters and return values in the controller. Resources won't allow you to capture important metadata (like the id, version-id, last modified date etc). By using ResourceEntry in my controller, this data can be passed around with the resource data and the WebApi framework can bind this metadata to the appropriate HTTP headers.
这篇关于HL7 FHIR序列化到ASP.NET Web API中的json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!