Конфигурация WCF Ад?
Я ненавижу установку WCF с конечными точками, поведением и т.д. Я считаю, что все эти вещи должны выполняться автоматически. Все, что я хочу сделать, это вернуть результат JSON из моей службы WCF. Вот моя конфигурация:
<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"/>
И у меня есть следующая реализация службы:
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; }
}
Когда я навещаю http://localhost:22059/ZombieService/KnownZombies
, выдается следующее сообщение:
Конечные точки с использованием "UriTemplate" не могут использоваться с "System.ServiceModel.Description.WebScriptEnablingBehavior".
Если я удалю WebScriptEnablingBehavior из web.config, я получаю следующую ошибку:
Сообщение с To 'http://localhost: 22059/ZombieService.svc/KnownZombies' не может быть обрабатывается в приемнике из-за несоответствия AddressFilter на EndpointDispatcher. Убедитесь, что отправитель и получатель Адреса Endpoint согласны.
ОБНОВЛЕНИЕ 1:
Я обновил конфигурацию до этого:
<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>
Теперь, когда я посещаю http://localhost:22059/ZombieService.svc/KnownZombies
, я получаю следующее сообщение в браузере:
Сообщение с To 'http://localhost: 22059/ZombieService.svc/KnownZombies' не может быть обрабатывается в приемнике из-за несоответствия AddressFilter на EndpointDispatcher. Убедитесь, что отправитель и получатель Адреса Endpoint согласны.
Ответы
Ответ 1
Взгляните на этот вопрос SO.
Изменить. Поскольку вы не указываете адрес своей службы, попробуйте нажать: http://localhost:22059/ZombieService.svc/KnownZombies (с .svc).
Я также думаю, что вам нужно поведение <webHttp />
, добавленное к вашему указанному положению конечной точки.
Изменить: попробуйте изменить определение конечной точки на следующее:
<service
name="HighOnCodingWebApps.ZombieService"
behaviorConfiguration="MyServiceTypeBehaviors">
<endpoint
address=""
binding="webHttpBinding"
behaviorConfiguration="SomeBehavior"
bindingConfiguration="default"
contract="HighOnCodingWebApps.IZombieService" />
</service>
Ответ 2
Вы пробовали WCF SvcConfigEditor? Он доступен из меню "Инструменты" в Visual Studio. Откройте ваш web/app.config с помощью SvcConfigEditor, чтобы получить помощь в GUI, чтобы все было правильно.
Ответ 3
Вы используете WebInvokeAttribute, который сообщает WCF по умолчанию принимать POST в качестве глагола. Поскольку вы пытаетесь получить к нему доступ посредством действия GET, оно игнорируется.
Вместо этого используйте WebGetAttribute.
В MSDN:
Если вы хотите, чтобы операция службы отвечала на GET, используйте Вместо этого используется WebGetAttribute.
Ответ 4
Мне лично не нравятся все параметры конфигурации, которые предлагает WCF (я рассказывал об этом до), а в вашем случае вам вообще не нужно использовать конфигурацию. Для простой службы для возврата JSON вы можете использовать хост службы factory, и там, где это делается (настройте конечную точку поведения webHttpBinding
/webHttp
), System.ServiceModel.Activation.WebServiceHostFactory
. В вашем случае вы можете:
- Удалите все из config (действительно, вам не нужна настройка вообще)
- Обновите файл .svc для ссылки на factory (см. ниже)
Что это. Вот что должно выглядеть .svc:
<%@ ServiceHost Language="C#" Service="HighOnCodingWebApps.ZombieService" Factory="System.ServiceModel.Activation.WebServiceHostFactory" %>
Еще одна вещь: я заметил, что ваш класс не украшен [ServiceContract]
, но у вас есть атрибут [WebGet]
в вашем методе в классе. Если интерфейс (IZombieService) - это тот, который украшен [ServiceContract]
, тогда метод в интерфейсе должен быть тем, который был украшен [WebGet]
. Вы также можете полностью обходить интерфейс и украсить класс ZombieService с помощью `[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; }
}
Ответ 5
Просто используйте ASP.NET Web API вместо WCF
Ответ 6
Я использую .net framework 4, VS2010.
Я сделал фиктивную ошибку в моей global.asax.cs, которая вместо создания экземпляра WebServiceHostFactory
Я ударил WebScriptServiceHostFactory через intellSense. В результате я получил ту же ошибку:
Конечные точки с использованием "UriTemplate" не могут использоваться с "System.ServiceModel.Description.WebScriptEnablingBehavior".
Я скорректировал экземпляр WebServiceHostFactory в my global.asax.cs, я больше не вижу ошибки.
Ответ 7
В WebGet
или WebInvoke
укажите BodyStyle
на WrappedRequest
, а затем удалите UriTemplate
. При вызове вашей службы используйте имя функции.
Надеюсь, что это поможет.
Пример:
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
void register(string name, string surname);