2013-02-13 30 views
9

Tôi đang viết một ứng dụng POC sử dụng Microsoft.ServiceBus.dll 1.0.0.0 (phiên bản .NET 3.5).Tự động gán kiểu nội dung phản hồi json trong WCF Azure Service Bus

Hợp đồng của tôi WCF và dịch vụ trông giống như sau:

[ServiceContract(Name="MyServiceContract", Namespace = "http://mydomain.com/")] 
internal interface IServiceContract 
{ 
    [WebInvoke(Method = "POST", UriTemplate = "/DoOperation")] 
    [OperationContract] 
    Stream RelayRequest(Stream requestBody); 
} 

[ServiceBehavior(Name = "Service1", Namespace = "http://mydomain.com/Service1/", InstanceContextMode = InstanceContextMode.Single)] 
internal class Service1 : IServiceContract 
{ 
    Stream RelayRequest(Stream requestBody) 
    { 
     var contents = GetJsonResponse(); 
     var responseStream = new MemoryStream(); 
     var streamWriter = new StreamWriter(responseStream); 
     streamWriter.AutoFlush = true; 
     var writer = new JsonTextWriter(streamWriter); 
     var serializer = new JsonSerializer(); 
     serializer.Serialize(responseStream, contents); 

     responseStream.Position = 0 // reset the position of the stream so that it's contents will be read from the beginning. 

     //Problem Line: 
     WebOperationContext.OutgoingResponse.ContentType = "application/json"; 
     return responseStream; 
    } 
} 

Điểm cuối nghe được cấu hình để sử dụng WebHttpRelayBinding:

  • SecurityMode: Giao thông vận tải
  • TransferMode: Đã phát

Khi tôi cố gắng chỉ định ContentType của phản hồi gửi đến "application/json" một lỗi không xảy ra nhưng yêu cầu gọi trở lại với mã trạng thái 504 (Thời gian chờ cổng).

Nếu tôi thay đổi ContentType thành "text/javascript", yêu cầu gọi trở lại với 200 (OK).

Một số điều cần lưu ý:

  • Các content-type không biết cho đến khi thời gian chạy vì vậy nó phải được gán tự động.
  • Nội dung của luồng là tinh khiết - 100% hợp lệ - json.
  • Mục đích chấp nhận và trả lại luồng là để chúng tôi có thể chấp nhận yêu cầu phát trực tiếp và dữ liệu luồng xuống cho khách hàng.
    • Mỗi yêu cầu/phản hồi có thể chứa tải trọng json nhỏ hoặc tài liệu 200MB.
  • Nếu bạn muốn repro - mã này sử dụng thư viện Newtonson Json để tuần tự hóa.

Tại sao điều này xảy ra và làm cách nào để khắc phục sự cố này?

CHỈNH SỬA: Mã trạng thái 504 có thể là một đoạn trích màu đỏ được suy ra bởi người chơi số mà tôi đang thử nghiệm. Gửi yêu cầu tương tự từ System.Net.Http.HttpClient cho biết kết nối đã bị đóng trước khi nhận được phản hồi.

CHỈNH SỬA: đặt loại nội dung thành nhiều thứ khác (bao gồm giá trị không nhạy cảm) hoạt động tốt. Loại nội dung duy nhất mà tôi có thể phá vỡ là ứng dụng/json

+0

Bạn có thể thêm thông tin từ tệp cấu hình của mình/cách bạn thiết lập dịch vụ không? Bạn đang sử dụng loại ràng buộc nào? – TheDude

+0

Như đã chỉ ra ở trên, chúng tôi sử dụng WebHttpRelayBinding. Điểm kết buộc/kết thúc này không được tạo bởi cấu hình, nó được tạo lập trình khi chạy. –

+0

À, tôi đoán là tôi đã có một loạt các mất trí nhớ đọc mô tả của bạn ... – TheDude

Trả lời

-1

Đây là cách tôi làm cho nó hoạt động nhưng đó là một dịch vụ WCF đơn giản được lưu trữ cục bộ trong IIS. Tôi không sử dụng Microsoft.ServiceBus hoặc Azure.

Câu trả lời của Fiddler đầu tiên. Nếu đây là những gì bạn đang tìm kiếm sau đó tiến hành để mã :)

HTTP/1.1 200 OK 
Cache-Control: private 
Content-Length: 121 
Content-Type: application/json; charset=utf-8 
Server: Microsoft-IIS/7.5 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 
Date: Thu, 04 Apr 2013 17:17:05 GMT 

[{"BoolValue":true,"StringValue":"blah"},{"BoolValue":false,"StringValue":"boo"},{"BoolValue":true,"StringValue":"floo"}] 

định nghĩa dịch vụ:

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" }, 
      }; 
     } 
    } 
} 

Và 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> 
+0

Giải pháp của bạn chỉ hoạt động vì bạn đã xóa tất cả sự phức tạp khỏi câu hỏi ban đầu đã gây ra sự cố ngay từ đầu. Như đã nêu trong câu hỏi ban đầu tôi cần phải tự động gán kiểu nội dung phản hồi, tôi cũng cần phải sử dụng Azure Service Bus để đạt được điều này. –

Các vấn đề liên quan