Методы REST недоступны при размещении службы wcf в IIS

У меня есть служба WCF REST, которая предоставляет метод в классе GreetService:

[ServiceContract]
public class GreetService
{
    [WebGet(UriTemplate = "greet/{name}")]
    public String GreetName(string name)
    {
        return "Hello " + name;
    }
}

Также я зарегистрировал маршрут в Global.asax:

RouteTable.Routes.Add(new ServiceRoute("GreetService", new WebServiceHostFactory(), typeof(GreetService)));

Теперь, когда я запускаю это непосредственно из Visual Studio, я могу использовать UriTemplate и вызывать этот метод, используя вызов GET для http://localhost:5432/GreetService/greet/JohnDoe

Однако после развертывания этого в IIS7 путем создания для него файла Greet.svc я наблюдаю следующее поведение:

Любые идеи, почему WebGetAttribute не работает в IIS? Или я что-то не так делаю?

РЕДАКТИРОВАТЬ: это часть ServiceModel моего файла web.config, который находится в каталоге, который использует IIS:

<system.serviceModel>
    <!-- <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> -->
    <standardEndpoints>
      <webHttpEndpoint>
        <!-- 
        Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
        via the attributes on the <standardEndpoint> element below
        -->
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
      </webHttpEndpoint>
    </standardEndpoints>
</system.serviceModel>

РЕДАКТИРОВАТЬ 2: ради полноты вот мой полный файл web.config:

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule"
           type="System.Web.Routing.UrlRoutingModule,
           System.Web, Version=4.0.0.0,
           Culture=neutral,
           PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
    <handlers>
      <add name="UrlRoutingHandler"
         preCondition="integratedMode"
         verb="*" path="UrlRouting.axd"
         type="System.Web.HttpForbiddenHandler, 
         System.Web, Version=4.0.0.0, Culture=neutral, 
         PublicKeyToken=b03f5f7f11d50a3a" />
    </handlers>
  </system.webServer>

  <system.serviceModel>
     <!--<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>--> 
    <standardEndpoints>
      <webHttpEndpoint>
        <!-- 
            Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
            via the attributes on the <standardEndpoint> element below
        -->
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>

</configuration>

4 ответа

Если вы определили свой маршрут:

new ServiceRoute("GreetService", .....

тогда вы сможете позвонить в свою службу по адресу

http://localhost:5432/YourVirtualDirectory/GreetService/greet/JohnDoe

и если ваше веб-приложение развернуто в корневом каталоге IIS (не в виртуальном каталоге), это будет:

http://localhost:5432/GreetService/greet/JohnDoe

При определении ServiceRoute это делается для того, чтобы избавиться от необходимости указывать Greet.svc файл, действительно - ServiceRoute запись уже содержит всю информацию, необходимую IIS для создания экземпляра вашей службы и вызова ее - нет необходимости включать файл *.svc в ваш URL (файл svc в основном содержит ту же информацию, что и ваш ServiceRoute запись имеет).

Измените строку в вашем global.asax.cs читать:

RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(GreetService)));

и поместите следующее в свой web.config прямо под корнем <configuration> узел:

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule"
           type="System.Web.Routing.UrlRoutingModule, 
          System.Web.Routing, Version=4.0.0.0, 
          Culture=neutral, 
          PublicKeyToken=31BF3856AD364E35" />

    </modules>
    <handlers>
      <add name="UrlRoutingHandler"
         preCondition="integratedMode"
         verb="*" path="UrlRouting.axd"
         type="System.Web.HttpForbiddenHandler, 
         System.Web, Version=4.0.0.0, Culture=neutral, 
         PublicKeyToken=b03f5f7f11d50a3a" />
    </handlers>
  </system.webServer>

(убедитесь, что вы используете правильную версию.NET) и посмотрите, что это для вас.

ПРИМЕЧАНИЕ: пожалуйста, опубликуйте web.config, хотя бы часть system.servicemodel.

Обычно вы используете либо конфигурацию на основе маршрута, либо файл.svc, но не оба, но это ортогонально вашей проблеме. FWIW, вы должны быть в состоянии уничтожить файл.svc, как только вы запустите службу и просто используете маршрут.

Так как вы можете генерировать WSDL и вызывать его, кажется, что у вас может не быть webhttp в качестве поведения конечной точки?

Убедитесь, что поведение конечной точки определено следующим образом (конечно, это может быть другое имя)

    <endpointBehaviors> 
        <behavior name="webHttpBehavior"> 
            <webHttp /> 
        </behavior> 
    </endpointBehaviors> 

и затем убедитесь, что ваша конечная точка службы включает поведение Configuration="webHttpBehavior"

Проблема в том, что в конфигурации машины отсутствует следующий раздел

<configSections>
    <sectionGroup name="system.serviceModel" type="System.ServiceModel.Configuration.ServiceModelSectionGroup, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <section name="standardEndpoints" type="System.ServiceModel.Configuration.StandardEndpointsSection, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
    </sectionGroup>
</configSections>

Добавьте его поверх web.config (после открывающего тега <configuration>) должен решить эту проблему.

Другие вопросы по тегам