WCF REST 服务流式 JSON 对象

问题描述

我需要一个 Windows 服务,其中 REST API 将一堆 JSON 对象转储到一个流中(内容类型:application/stream+json)。

示例响应(不是对象数组):

{ id: 1,name: "name 1" }
{ id: 2,name: "name 2" }
{ id: 3,name: "name 3" }
{ id: 4,name: "name 4" }

可以在 WCF REST 中执行此操作吗?或者我应该尝试其他的东西?

解决方法

几天后,我找到了解决方案。首先,我修改 App.config 文件并将绑定配置添加到允许流式响应的端点。接下来,服务合约的操作必须有返回流。然后在服务契约的实现中,我将传出响应内容类型设置为“application/stream+json”,使用 DataContractJsonSerializer 序列化所有对象并写入 MemoryStream。最后,我将 MemoryStream 的位置设置为零,然后返回该流。

示例代码如下。

App.config:

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  <services>
    <service name="WinService.WcfService">
      <endpoint address="" binding="webHttpBinding" bindingConfiguration="webHttpBindingStreamedResponse" contract="WinService.IWcfService" behaviorConfiguration="webHttp" />
      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    </service>
  </services>
  <bindings>
    <webHttpBinding>
      <binding name="webHttpBindingStreamedResponse" transferMode="StreamedResponse" maxReceivedMessageSize="67108864"/>
    </webHttpBinding>
  </bindings>
  <behaviors>
    <serviceBehaviors>
      <behavior>
        <!-- To avoid disclosing metadata information,set the values below to false before deployment -->
        <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
        <!-- To receive exception details in faults for debugging purposes,set the value below to true.  Set to false before deployment 
        to avoid disclosing exception information -->
        <serviceDebug includeExceptionDetailInFaults="True" />
      </behavior>
    </serviceBehaviors>
    <endpointBehaviors>
      <behavior name="webHttp">
        <webHttp />
      </behavior>
    </endpointBehaviors>
  </behaviors>
</system.serviceModel>

服务合同:

[ServiceContract]
public interface IWcfService
{
  [OperationContract]
  [WebGet(UriTemplate = "/stream/{param}",ResponseFormat = WebMessageFormat.Json)]
  Stream GetJsonStreamedObjects(string param);
}

ServiceContract的实施:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class WcfService : IWcfService
{
  public Stream GetJsonStreamedObjects(string param)
  {
    var stream = new MemoryStream();
    var serializer = new DataContractJsonSerializer(typeof(JsonObjectDataContract));

    WebOperationContext.Current.OutgoingResponse.ContentType = "application/stream+json";

    foreach (JsonObjectDataContract jsonObjectDataContract in Repository.GetJsonObjectDataContracts(param))
    {
      serializer.WriteObject(stream,jsonObjectDataContract);
    }
    stream.Position = 0;
    return stream;
  }
}