C# 在WCF Azure服务总线中动态分配json响应内容类型

C# 在WCF Azure服务总线中动态分配json响应内容类型,c#,wcf,azure,wcf-rest,azureservicebus,C#,Wcf,Azure,Wcf Rest,Azureservicebus,我正在编写一个使用Microsoft.ServiceBus.dll 1.0.0.0(.NET 3.5版本)的POC应用程序 我的WCF合同和服务如下所示: 侦听端点配置为使用WebHttpRelayBinding: 安全模式:传输 传输模式:流式传输 当我尝试将传出响应的ContentType分配给“application/json”时,没有发生错误,但调用请求返回状态代码504(网关超时) 如果我将ContentType更改为“text/javascript”,调用请求将返回200(OK

我正在编写一个使用Microsoft.ServiceBus.dll 1.0.0.0(.NET 3.5版本)的POC应用程序

我的WCF合同和服务如下所示:

侦听端点配置为使用WebHttpRelayBinding:

  • 安全模式:传输
  • 传输模式:流式传输
当我尝试将传出响应的ContentType分配给“application/json”时,没有发生错误,但调用请求返回状态代码504(网关超时)

如果我将ContentType更改为“text/javascript”,调用请求将返回200(OK)

需要注意的一些事项:

  • 内容类型在运行时之前是未知的,因此必须动态分配
  • 流的内容是纯-100%有效-json
  • 接受和返回流的目的是为了能够接受流式请求并将数据流式传输到客户端。
    • 每个请求/响应可以包含一个小的json负载或一个200MB的文档
  • 如果您想重新编译-此代码使用Newtonsoft Json库进行序列化
为什么会发生这种情况?我如何解决

编辑:504状态代码可能是我正在测试的fiddler推断出来的一条红鲱鱼。 从System.Net.Http.HttpClient发送相同的请求表示在收到响应之前连接已关闭


编辑:将内容类型设置为几乎任何其他类型(包括非感官值)都可以正常工作。我唯一可以打破它的内容类型是application/json

这是我如何使其工作的,但它是一个简单的WCF服务,在IIS中本地托管。我不使用Microsoft.ServiceBus或Azure

第一小提琴手的回答。如果这是您要查找的内容,请转至代码:)

服务定义:

namespace yourNS
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        [WebGet(UriTemplate = "/CT", ResponseFormat = WebMessageFormat.Json)]
        List<CompositeType> GetData();
    }


    [DataContract]
    public class CompositeType
    {
        [DataMember]
        public bool BoolValue { get; set; }

        [DataMember]
        public string StringValue { get; set; }
    }

    public class Service1 : IService1
    {
        public List<CompositeType> GetData()
        {
            return new List<CompositeType>
            {
                new CompositeType { BoolValue = true, StringValue = "blah" },
                new CompositeType { BoolValue = false, StringValue = "boo" },
                new CompositeType { BoolValue = true, StringValue = "floo" },
            };
        }
    }
}
namespace yourNS
{
[服务合同]
公共接口IService1
{
[经营合同]
[WebGet(UriTemplate=“/CT”,ResponseFormat=WebMessageFormat.Json)]
List GetData();
}
[数据合同]
公共类复合类型
{
[数据成员]
公共布尔布尔值{get;set;}
[数据成员]
公共字符串StringValue{get;set;}
}
公共类服务1:IService1
{
公共列表GetData()
{
返回新列表
{
新的复合类型{BoolValue=true,StringValue=“blah”},
新的复合类型{BoolValue=false,StringValue=“boo”},
新的复合类型{BoolValue=true,StringValue=“floo”},
};
}
}
}
和web.config

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="yourNS.Service1">
        <endpoint 
          address="" 
          binding="webHttpBinding" 
          behaviorConfiguration="MyBehave"
          contract="yourNS.IService1" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="MyBehave">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="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>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>


能否从配置文件中添加信息/如何设置服务?您使用哪种类型的绑定?如上所述,我们使用WebHttpRelayBinding。这个绑定/终结点不是由配置创建的,它是在运行时通过编程创建的。啊,我猜我在阅读你的描述时有一系列的思维失误……解决这个问题有什么进展吗?不幸的是没有,没有。我们最终使用自定义标题解决了这个问题。您的解决方案之所以有效,是因为您已从最初导致问题的原始问题中删除了所有复杂性。如原始问题中所述,我需要动态分配响应内容类型,我还需要使用Azure服务总线来实现这一点。
namespace yourNS
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        [WebGet(UriTemplate = "/CT", ResponseFormat = WebMessageFormat.Json)]
        List<CompositeType> GetData();
    }


    [DataContract]
    public class CompositeType
    {
        [DataMember]
        public bool BoolValue { get; set; }

        [DataMember]
        public string StringValue { get; set; }
    }

    public class Service1 : IService1
    {
        public List<CompositeType> GetData()
        {
            return new List<CompositeType>
            {
                new CompositeType { BoolValue = true, StringValue = "blah" },
                new CompositeType { BoolValue = false, StringValue = "boo" },
                new CompositeType { BoolValue = true, StringValue = "floo" },
            };
        }
    }
}
<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="yourNS.Service1">
        <endpoint 
          address="" 
          binding="webHttpBinding" 
          behaviorConfiguration="MyBehave"
          contract="yourNS.IService1" />
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="MyBehave">
          <webHttp />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="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>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>