Служба WCF REST не работает - проблема с конфигурацией? - PullRequest
1 голос
/ 02 ноября 2011

У меня есть служба WCF с пользовательской привязкой, размещенная в IIS (IIS Express в разработке) со следующим контрактом на обслуживание:

[ServiceContract]
public interface IServer
{
    [OperationContract]
    StreamCollection GetStreams(Guid poolKey);

    [OperationContract]
    PoolCollection GetPools();

    [OperationContract]
    StreamEntity GetStream(Guid poolKey, string localIndex);    
}

Он работает нормально (из клиента, а также я вижу, что его метаданные обнаружены нормально)в WCFTestClient).
Я должен представить его функциональность как REST, поэтому я создал новый контракт, как показано ниже

[ServiceContract]
public interface IRestServer
{
    [OperationContract(Name="GetStreamsREST")]
    [WebGet(UriTemplate = "pool/{poolKey}/streams")]
    StreamCollection GetStreams(string poolKey);

    [OperationContract(Name = "GetPoolsREST")]
    [WebGet(UriTemplate = "pools")]
    PoolCollection GetPools();

    [OperationContract(Name = "GetStreamREST")]
    [WebGet(UriTemplate = "pool/{poolKey}/stream/{localIndex}")]
    StreamEntity GetStream(string poolKey, string localIndex);
}

У меня оба интерфейса реализованы в одном классе обслуживания.Файл web.config имеет вид

<behaviors>
  <endpointBehaviors>
    <behavior name="webHttp">
      <webHttp/>
    </behavior>
  </endpointBehaviors>
</behaviors>
<bindings>
  <customBinding>
    <binding name="CustomBinding">
      <binaryMessageEncoding />
      <httpTransport maxReceivedMessageSize="655360" />
    </binding>
  </customBinding>
</bindings>
<services>
  <service behaviorConfiguration="ServiceBehavior" name="MyServ.Server.Server">
    <endpoint address="" binding="customBinding" bindingConfiguration="CustomBinding" contract="MyServ.Server.IServer" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <endpoint address="rest" behaviorConfiguration="webHttp" binding="webHttpBinding" contract="MyServ.Server.IRestServer" />
  </service>
</services>

Однако, когда я просматриваю доступ к службе, используя rest, с URL-адресом, подобным

http://localhost:<myport>/Service.svc/pools 
http://localhost:<myport>/Service.svc/pool/somekey/streams
http://localhost:<myport>/Service.svc/pool/somekey/streams

, я получаю ошибку 404.

Я поставил точку останова в некоторых методах и подключил отладчик к процессу IIS, но, похоже, ничего не вызывается.

Если я проверяю метаданные службы с помощью WCFTestClient, он просто видит IService, но не IRestService.Это нормально? РЕДАКТИРОВАТЬ : Да, похоже, что это ( отметьте это )

Спасибо за любые предложения.

Ответы [ 3 ]

2 голосов
/ 03 ноября 2011

Конечные точки REST не предоставляют метаданные способом, который может быть использован WCFTestClient, что объясняет, почему вы не можете получить к ним доступ.И адрес, который вы просматриваете, неверен, так как вы указали адрес конечной точки для конечной точки REST как «rest», вам нужно получить к ним доступ в виде, подобном

http://localhost:port/Service.svc/rest/pool/myPoolKey/streams
http://localhost:port/Service.svc/rest/pools
http://localhost:port/Service.svc/rest/myPoolKey/stream/1

Еще одна вещь: атрибут Nameв атрибуте [OperationContract] не имеет значения для конечных точек REST, поэтому вы можете удалить его (хотя это не помешает иметь его там).Кроме того, если вы используете .NET 4.0, вам даже не нужен атрибут [OperationContract], поскольку у вас уже есть [WebGet], поэтому ваш интерфейс можно определить как

[ServiceContract]
public interface IRestServer
{
    [WebGet(UriTemplate = "pool/{poolKey}/streams")]
    StreamCollection GetStreams(string poolKey);

    [WebGet(UriTemplate = "pools")]
    PoolCollection GetPools();

    [WebGet(UriTemplate = "pool/{poolKey}/stream/{localIndex}")]
    StreamEntity GetStream(string poolKey, string localIndex);
}
1 голос
/ 03 ноября 2011

Спасибо всем за все предложения.Тем не менее, я наконец решил проблему.

Проблема в том, что я до сих пор не знаю, в чем проблема, но я решил пойти другим и более «чистым» путем.

Так чтоЯ сделал, чтобы создать другой файл SVC службы, RestServer, где я реализовал методы REST

И я изменил настройки в веб-конфигурации, чтобы иметь две разные службы, одну для оригинальной (чистый WCF) и одну дляREST один, как показано ниже

<service name="MyServ.Server.RestServer" >
    <endpoint address="" name="RESTEndpoint" behaviorConfiguration="webHttp" binding="webHttpBinding" contract="MyServ.Server.IRestServer" />
</service> 

И это помогло.

На самом деле, я должен использовать этот подход с самого начала, чтобы соответствовать принципу единой ответственности ...

1 голос
/ 03 ноября 2011

Можете ли вы опубликовать свой код о том, как вы вызываете службу WCF? У меня была похожая проблема на днях, когда клиентское приложение вызывало страницу с HTTP POST вместо HTTP GET и, таким образом, получало ошибку 404.

[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/GuessWhat")]

против

[WebGet(UriTemplate = "/GuessWhat/{variable}", ResponseFormat = WebMessageFormat.Json)] 

Я не уверен, есть ли у вашего сервиса это или нет, но убедитесь, что сервис, реализующий ваш сервисный контракт, имеет этот атрибут.

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...