如何移除FHIR JSON输出中多余的value嵌套结构?
问题
开发.NET Core应用时,基于数据库结果创建FHIR资源,生成FHIR Bundle的JSON响应出现多余的value嵌套结构,需要移除这些层级,使输出符合标准FHIR格式。
当前JSON输出
{ "id": { "value": "bundle-example" }, "type": { "value": "searchset" }, "total": { "value": 5 }, "entry": [ { "fullUrl": { "value": "http://example.org/fhir/Observation/8393939" }, "resource": { "id": { "value": "8393939" }, "status": { "value": "final" }, "code": { "coding": [ { "system": { "value": "http://loinc.org" }, "code": { "value": "1988-5" }, "display": { "value": "CRP" } } ] } // ... other fields } } // ... other entries ] }
期望JSON结构
{ "resourceType": "Bundle", "id": "bundle-example", "type": "searchset", "total": 5, "entry": [ { "fullUrl": "http://example.org/fhir/Observation/8393939", "resource": { "resourceType": "Observation", "id": "8393939", "status": "final", "code": { "coding": [ { "system": "http://loinc.org", "code": "1988-5", "display": "CRP" } ] } // ... other fields } } // ... other entries ] }
相关代码
using Hl7.Fhir.Model; using System; using System.Data; using System.Collections.Generic; using FHIR.PoC.Data; namespace FHIR.PoC.Service { public class ObservationService { private readonly SpecimenRepository m_specimenRepository; public ObservationService(SpecimenRepository specimenRepository) { m_specimenRepository = specimenRepository; } public Bundle MapToObservations(DataTable dtDbResults, bool bIncludeSpecimen) { var bundle = new Bundle { Id = "bundle-example", Type = Bundle.BundleType.Searchset, Total = dtDbResults.Rows.Count, Entry = new List<Bundle.EntryComponent>() }; foreach (DataRow drRow in dtDbResults.Rows) { var observation = new Observation { Id = drRow["zissample_id"].ToString() ?? "null", Status = drRow["ZISRESULTSTATUS_ID"].ToString() == "8000013" ? ObservationStatus.Final : ObservationStatus.Preliminary, Code = new CodeableConcept { Coding = new List<Coding> { new Coding { System = "http://loinc.org", Code = drRow["LOINC_CODE"] != DBNull.Value ? drRow["LOINC_CODE"].ToString() : null, Display = drRow["MEASURE_CODE"] != DBNull.Value ? drRow["MEASURE_CODE"].ToString() : null } } }, Subject = new ResourceReference($"Patient/{drRow["SOURCE_ID"].ToString()}"), Effective = GetEffectiveDate(drRow), Issued = drRow["FIRSTREPORTDATETIME"] != DBNull.Value ? (DateTimeOffset?)Convert.ToDateTime(drRow["FIRSTREPORTDATETIME"]) : null, Performer = new List<ResourceReference> { new ResourceReference("Practitioner/VasteWaardeLabTrain") }, Value = GetObservationValue(drRow) }; ProcessReferenceRangeIfPresent(drRow, observation); if (bIncludeSpecimen) { ProcessSpecimen(drRow, observation); } bundle.Entry.Add(new Bundle.EntryComponent { FullUrl = $"http://example.org/fhir/Observation/{observation.Id}", Resource = observation }); } return bundle; } } }
解决方案
出现value嵌套是因为使用的FHIR.NET库默认采用原始元素序列化模式,而非标准FHIR JSON格式。只需调整序列化配置,就能输出符合要求的结构:
1. 使用FHIR专用序列化器
不要用.NET默认的System.Text.Json或Newtonsoft.Json直接序列化FHIR对象,必须使用库自带的序列化工具:
using Hl7.Fhir.Serialization; // 序列化Bundle为标准FHIR JSON var serializer = new FhirJsonSerializer(new SerializerSettings { Pretty = true, // 可选,格式化输出便于阅读 UseXmlSerialization = false }); string standardFhirJson = serializer.SerializeToString(bundle);
2. ASP.NET Core项目配置全局格式化器
如果是在API接口中返回FHIR资源,直接在Startup/Program.cs中注册FHIR格式化器,控制器返回Bundle对象时会自动按标准格式序列化:
using Hl7.Fhir.AspNetCore; // Program.cs中添加 builder.Services.AddControllers() .AddFhirFormatters();
3. 确认代码逻辑无需调整
你当前构建Bundle和Observation的属性赋值方式是正确的(如bundle.Id = "bundle-example"),问题不在对象构建环节,只要用FHIR专用序列化器,这些属性会自动转换为标准键值对,而非{ "value": "xxx" }结构。
4. 自动补充resourceType字段
标准FHIR JSON要求的resourceType字段,FHIR库会自动为Bundle、Observation等资源类添加,无需手动赋值,正确序列化后会自动出现在输出中。
内容的提问来源于stack exchange,提问作者Salt
相关产品推荐
相关产品推荐

