2011-08-11 41 views
11

Tôi ghét thiết lập WCF với điểm cuối, hành vi, v.v. Tôi tin rằng tất cả những điều này sẽ được thực hiện tự động. Tất cả những gì tôi muốn làm là trả về kết quả JSON từ dịch vụ WCF của tôi. Dưới đây là cấu hình của tôi:Địa chỉ WCF Địa ngục?

<system.serviceModel> 
<bindings> 
    <webHttpBinding> 
    <binding name="default"/> 
    </webHttpBinding> 
</bindings> 
<services> 
    <service name="HighOnCodingWebApps.ZombieService" 
    behaviorConfiguration="MyServiceTypeBehaviors"> 
    <endpoint address="" binding="webHttpBinding" 
     bindingConfiguration="default" 
     contract="HighOnCodingWebApps.IZombieService" 
     behaviorConfiguration="webScriptEnablingBehavior"/> 
    </service> 
</services> 

<behaviors> 
    <endpointBehaviors> 
    <behavior name="webScriptEnablingBehavior"> 
     <enableWebScript/> 
    </behavior> 
    </endpointBehaviors> 

    <serviceBehaviors> 
    <behavior name="MyServiceTypeBehaviors"> 
     <serviceMetadata httpGetEnabled="true"/> 


    </behavior> 
    </serviceBehaviors> 
</behaviors> 

<serviceHostingEnvironment aspNetCompatibilityEnabled="false"/> 

Và tôi có thực hiện dịch vụ sau:

public class ZombieService : IZombieService 
    { 
     [WebInvoke(Method = "GET", 
        ResponseFormat = WebMessageFormat.Json, 
        UriTemplate = "KnownZombies")] 
     public Zombie GetZombie() 
     { 
      return new Zombie() { Name = "Mohammad Azam"}; 
     } 
    } 

    public class Zombie 
    { 
     public string Name { get; set; } 
    } 

Khi tôi ghé thăm http://localhost:22059/ZombieService/KnownZombies nói được thông báo sau:

thiết bị đầu cuối sử dụng 'UriTemplate' không thể được sử dụng với 'System.ServiceModel.Description.WebScriptEnablingBehavior'.

Nếu tôi loại bỏ các WebScriptEnablingBehavior từ web.config tôi nhận được lỗi sau:

The message with To 'http://localhost:22059/ZombieService.svc/KnownZombies' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.

UPDATE 1:

tôi cập nhật cấu hình như thế này:

<system.serviceModel> 
    <bindings> 
     <webHttpBinding> 
     <binding name="default"/> 
     </webHttpBinding> 
    </bindings> 
    <services> 
     <service name="HighOnCodingWebApps.ZombieService" 
     behaviorConfiguration="MyServiceTypeBehaviors"> 
     <endpoint address="http://localhost:22059/ZombieService.svc" binding="webHttpBinding" 
      bindingConfiguration="default" 
      contract="HighOnCodingWebApps.IZombieService" 
      /> 
     </service> 
    </services> 

    <behaviors> 
     <endpointBehaviors> 
     <behavior name="SomeBehavior"> 
      <webHttp /> 
     </behavior> 
     </endpointBehaviors> 
     <serviceBehaviors> 
     <behavior name="MyServiceTypeBehaviors"> 

      <serviceMetadata httpGetEnabled="true"/> 
     </behavior> 
     </serviceBehaviors> 
    </behaviors> 

    </system.serviceModel> 

Bây giờ khi Tôi truy cập http://localhost:22059/ZombieService.svc/KnownZombies Tôi nhận được thông báo sau trong trình duyệt:

The message with To 'http://localhost:22059/ZombieService.svc/KnownZombies' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.

+2

Không kéo lên bất cứ điều gì? Bạn có thể thử đăng nội dung nào đó hữu ích và có thể bao gồm câu hỏi không? –

+0

Kiểm tra WCF 4.0 - nó đã khắc phục ** rất nhiều ** đau đầu cấu hình! Đọc [Giới thiệu của nhà phát triển đến WCF 4] (http://msdn.microsoft.com/en-us/library/ee354381.aspx) để biết thêm chi tiết. –

+0

cập nhật câu hỏi – azamsharp

Trả lời

5

Hãy xem this SO question.

Chỉnh sửa: Vì bạn không chỉ định địa chỉ cho dịch vụ của mình, hãy thử nhấn: http://localhost:22059/ZombieService.svc/KnownZombies (với .svc).

Tôi cũng nghĩ rằng bạn cần hành vi <webHttp /> được thêm vào hành vi điểm cuối được chỉ định của bạn.

Edit: Hãy thử thay đổi định nghĩa endpoint của bạn như thế này:

<service 
    name="HighOnCodingWebApps.ZombieService" 
    behaviorConfiguration="MyServiceTypeBehaviors"> 

    <endpoint 
    address="" 
    binding="webHttpBinding" 
    behaviorConfiguration="SomeBehavior" 
    bindingConfiguration="default" 
    contract="HighOnCodingWebApps.IZombieService" /> 

</service> 
+0

Xem bài đăng cập nhật! – azamsharp

+0

Đánh vào là giết tôi ... Thay vào đó, tôi sẽ chỉnh sửa câu trả lời của mình. – BrandonZeider

10

Bạn đã thử WCF SvcConfigEditor? Nó có sẵn từ trình đơn Tools trong Visual Studio. Mở web/app.config của bạn với SvcConfigEditor để có được trợ giúp GUI về việc làm mọi thứ đúng.

1

Bạn đang sử dụng WebInvokeAttribute để thông báo cho WCF theo mặc định để chấp nhận POST làm động từ. Vì bạn đang cố gắng truy cập nó thông qua một hành động GET, nó đang bị bỏ qua.

Thay vào đó hãy sử dụng WebGetAttribute.

mỗi MSDN:

If you want a service operation to respond to GET, use the WebGetAttribute instead.

+0

Tôi đã thay đổi nó thành [WebGet (ResponseFormat = WebMessageFormat.Json, UriTemplate = "KnownZombies")] Zombie công cộng GetZombie() { trả về Zombie mới() {Name = "Mohammad Azam"}; } nhưng kết quả tương tự – azamsharp

1

Cá nhân tôi không thích tất cả các tùy chọn cấu hình mà WCF cung cấp (Tôi đã ranted about it before), và trong trường hợp của bạn, bạn không cần phải sử dụng cấu hình. Đối với dịch vụ đơn giản để trả lại JSON, bạn có thể sử dụng nhà máy máy chủ dịch vụ và có một chính xác (thiết lập điểm cuối hành vi webHttpBinding/webHttp), System.ServiceModel.Activation.WebServiceHostFactory.Trong trường hợp của bạn, bạn có thể:

  • Hủy bỏ tất cả mọi thứ từ cấu hình (thực sự, bạn không cần phải cấu hình gì cả)
  • Cập nhật tập tin .svc của bạn để tham khảo nhà máy đó (xem dưới đây)

Vậy đó. Dưới đây là những gì các .svc nên hình như:

<%@ ServiceHost Language="C#" Service="HighOnCodingWebApps.ZombieService" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %> 

Một điều nữa: tôi nhận thấy rằng lớp học của bạn không được trang trí với [ServiceContract], nhưng bạn có một thuộc tính [WebGet] trong phương pháp của bạn trong lớp. Nếu giao diện (IZombieService) là giao diện được trang trí với [ServiceContract], thì phương thức trong giao diện phải là phương thức được trang trí với [WebGet]. Bạn cũng có thể bỏ qua hoàn toàn giao diện và trang trí cho ZombieService lớp với `[ServiceContract].

[ServiceContract] 
public class ZombieService 
{ 
    [WebGet(ResponseFormat = WebMessageFormat.Json, 
      UriTemplate = "KnownZombies")] 
    public Zombie GetZombie() 
    { 
     return new Zombie() { Name = "Mohammad Azam"}; 
    } 
} 

public class Zombie 
{ 
    public string Name { get; set; } 
} 
0

Chỉ cần sử dụng ASP.NET Web API thay vì WCF

+0

+1 để hủy bỏ phiếu giảm giá. WCF cực kỳ kém phù hợp với nhiệm vụ trả lại một số nội dung JSON cho một yêu cầu HTTP, mọi thứ sẽ đơn giản hơn nhiều nếu bạn sử dụng một công cụ thực sự phù hợp với nhiệm vụ. – Carson63000

+4

Mặc dù đây có thể là lời khuyên tốt nhưng đó không phải là câu trả lời cho câu hỏi. Các cửa sổ pop up nhỏ khi bạn viết một câu trả lời cụ thể nói để tránh làm cho báo cáo dựa trên ý kiến. – sanpaco

0

Tôi đang sử dụng .NET Framework 4, VS2010. Tôi đã mắc sai lầm giả trong global.asax.cs của mình thay vì tạo một cá thể của WebServiceHostFactory Tôi đã đục WebScriptServiceHostFactory thông qua intellSense. Kết quả là tôi đã gặp lỗi tương tự:

Điểm cuối sử dụng 'UriTemplate' không thể được sử dụng với 'System.ServiceModel.Description.WebScriptEnablingBehavior'.

tôi sửa chữa các ví dụ để WebServiceHostFactory trong global.asax.cs của tôi, tôi không thấy lỗi nữa.

+0

Có một thẻ để bật WebScript nhưng không phải để vô hiệu hóa nó, do đó bạn có thể mong đợi rằng việc không thêm thẻ sẽ vô hiệu hóa nó. Nhưng nó chỉ đã được giải quyết khi tôi thêm thẻ rõ ràng: Jos

0

Trong số WebGet hoặc WebInvoke Chỉ định BodyStyle đến WrappedRequest, sau đó xóa UriTemplate. Khi gọi dịch vụ của bạn, hãy sử dụng tên hàm.

Hy vọng điều đó sẽ hữu ích.

Ví dụ:

[OperationContract] 
    [WebInvoke(Method = "POST", 
     BodyStyle = WebMessageBodyStyle.WrappedRequest, 
     RequestFormat = WebMessageFormat.Json, 
     ResponseFormat = WebMessageFormat.Json)] 
    void register(string name, string surname); 
Các vấn đề liên quan