Методы 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 я наблюдаю следующее поведение:
- Я могу позвонить http://localhost:5432/Greet.svc и он говорит, что служба была создана
- Я могу указать wcftestclient на http://localhost:5432/Greet.svc?wsdl для генерации тестового клиента, который может напрямую вызывать GreetName()
- Однако я не могу вызвать http://localhost:5432/Greet.svc/GreetService/greet/JohnDoe или http://localhost:5432/Greet.svc/greet/JohnDoe, хотя я ожидал, что смогу, так как я указал пустой относительный адрес конечной точки в соответствующем файле web.config до размещения его в IIS7.
Любые идеи, почему 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>
) должен решить эту проблему.