无法从 POST/PUT 请求中获取资源(.NET FHIR 客户端,网络 api 2)
Can't get Resource from POST/PUT request (.NET FHIR client, web api 2)
当我尝试使用 .NET FHIR API 向 asp.net Web API 2 服务器发送 POST / PUT 请求时,我收到错误消息:
Hl7.Fhir.Rest.FhirOperationException: the operation failed due to a
client error (UnsupportedMediaType). The body has no content.
1) 我是否需要创建某种媒体类型处理程序/格式化程序?
2) 是否有代码实现 .NET FHIR 最佳实践的开源服务器API?
我查看了 Fiddler,似乎客户端在正文中发送了正确的 JSON
fhirClient = new FhirClient(serverUrl);
fhirClient.PreferredFormat = ResourceFormat.Json;
Patient patient = new Patient();
//fill patient
var response = fhirClient.Update(patient);
...
// 网络 api 2 服务器:
WebApiConfig.cs:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/fhir+json"));
我试过了:
[HttpPut]
public void Update([FromBody] Resource resource, string id = null)
{
// updating logic
}
//or
[HttpPut]
public void Update(Resource resource, string id = null)
{
// updating logic
}
但是,当我尝试
[HttpPut]
public void Update([FromBody] object resource, string id = null)
{
我可以在 "object" 内部看到反序列化的 Patient 并使用 jsonParser 将其取回
看来,我必须自己编写 Fhir MediaTypeFormatter
我用谷歌搜索并找到 this code:
public class JsonFhirFormatter : FhirMediaTypeFormatter
{
private readonly FhirJsonParser _parser = new FhirJsonParser();
private readonly FhirJsonSerializer _serializer = new FhirJsonSerializer();
public JsonFhirFormatter() : base()
{
foreach (var mediaType in ContentType.JSON_CONTENT_HEADERS)
SupportedMediaTypes.Add(new MediaTypeHeaderValue(mediaType));
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType = FhirMediaType.GetMediaTypeHeaderValue(type, ResourceFormat.Json);
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
try
{
var body = base.ReadBodyFromStream(readStream, content);
if (typeof(Resource).IsAssignableFrom(type))
{
Resource resource = _parser.Parse<Resource>(body);
return Task.FromResult<object>(resource);
}
else
{
throw Error.Internal("Cannot read unsupported type {0} from body", type.Name);
}
}
catch (FormatException exception)
{
throw Error.BadRequest("Body parsing failed: " + exception.Message);
}
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
using(StreamWriter streamwriter = new StreamWriter(writeStream))
using (JsonWriter writer = new JsonTextWriter(streamwriter))
{
SummaryType summary = requestMessage.RequestSummary();
if (type == typeof(OperationOutcome))
{
Resource resource = (Resource)value;
_serializer.Serialize(resource, writer, summary);
}
else if (typeof(Resource).IsAssignableFrom(type))
{
Resource resource = (Resource)value;
_serializer.Serialize(resource, writer, summary);
}
else if (typeof(FhirResponse).IsAssignableFrom(type))
{
FhirResponse response = (value as FhirResponse);
if (response.HasBody)
{
_serializer.Serialize(response.Resource, writer, summary);
}
}
}
return Task.CompletedTask;
}
}
并在Global.asax
中注册
事实上,另请参阅此处:HL7 FHIR serialisation to json in asp.net web api - 该答案基于您在上面找到的代码。
其中有几个选项,包括 github 上的开源 fhir-net-web-api 项目。
有一个aspnetcore版本,还有一个完整的框架owin版本。
检查那里的示例项目以了解如何使用它们。
当我尝试使用 .NET FHIR API 向 asp.net Web API 2 服务器发送 POST / PUT 请求时,我收到错误消息:
Hl7.Fhir.Rest.FhirOperationException: the operation failed due to a
client error (UnsupportedMediaType). The body has no content.
1) 我是否需要创建某种媒体类型处理程序/格式化程序?
2) 是否有代码实现 .NET FHIR 最佳实践的开源服务器API?
我查看了 Fiddler,似乎客户端在正文中发送了正确的 JSON
fhirClient = new FhirClient(serverUrl);
fhirClient.PreferredFormat = ResourceFormat.Json;
Patient patient = new Patient();
//fill patient
var response = fhirClient.Update(patient);
...
// 网络 api 2 服务器:
WebApiConfig.cs:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/fhir+json"));
我试过了:
[HttpPut]
public void Update([FromBody] Resource resource, string id = null)
{
// updating logic
}
//or
[HttpPut]
public void Update(Resource resource, string id = null)
{
// updating logic
}
但是,当我尝试
[HttpPut]
public void Update([FromBody] object resource, string id = null)
{
我可以在 "object" 内部看到反序列化的 Patient 并使用 jsonParser 将其取回
看来,我必须自己编写 Fhir MediaTypeFormatter 我用谷歌搜索并找到 this code:
public class JsonFhirFormatter : FhirMediaTypeFormatter
{
private readonly FhirJsonParser _parser = new FhirJsonParser();
private readonly FhirJsonSerializer _serializer = new FhirJsonSerializer();
public JsonFhirFormatter() : base()
{
foreach (var mediaType in ContentType.JSON_CONTENT_HEADERS)
SupportedMediaTypes.Add(new MediaTypeHeaderValue(mediaType));
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType = FhirMediaType.GetMediaTypeHeaderValue(type, ResourceFormat.Json);
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
try
{
var body = base.ReadBodyFromStream(readStream, content);
if (typeof(Resource).IsAssignableFrom(type))
{
Resource resource = _parser.Parse<Resource>(body);
return Task.FromResult<object>(resource);
}
else
{
throw Error.Internal("Cannot read unsupported type {0} from body", type.Name);
}
}
catch (FormatException exception)
{
throw Error.BadRequest("Body parsing failed: " + exception.Message);
}
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
using(StreamWriter streamwriter = new StreamWriter(writeStream))
using (JsonWriter writer = new JsonTextWriter(streamwriter))
{
SummaryType summary = requestMessage.RequestSummary();
if (type == typeof(OperationOutcome))
{
Resource resource = (Resource)value;
_serializer.Serialize(resource, writer, summary);
}
else if (typeof(Resource).IsAssignableFrom(type))
{
Resource resource = (Resource)value;
_serializer.Serialize(resource, writer, summary);
}
else if (typeof(FhirResponse).IsAssignableFrom(type))
{
FhirResponse response = (value as FhirResponse);
if (response.HasBody)
{
_serializer.Serialize(response.Resource, writer, summary);
}
}
}
return Task.CompletedTask;
}
}
并在Global.asax
中注册事实上,另请参阅此处:HL7 FHIR serialisation to json in asp.net web api - 该答案基于您在上面找到的代码。
其中有几个选项,包括 github 上的开源 fhir-net-web-api 项目。 有一个aspnetcore版本,还有一个完整的框架owin版本。 检查那里的示例项目以了解如何使用它们。