WCF配置地狱?

时间:2011-08-11 16:50:37

标签: c# .net wcf

我讨厌使用端点,行为等进行WCF设置。我相信所有这些事情都应该自动执行。我想要做的就是从我的WCF服务返回JSON结果。这是我的配置:

<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'一起使用。

如果我从web.config中删除了WebScriptEnablingBehavior,我收到以下错误:

  

带有To的消息   'http:// localhost:22059 / ZombieService.svc / KnownZombies'不能   由于地址过滤器不匹配而在接收器处理   EndpointDispatcher。检查发件人和收件人   EndpointAddresses同意。

更新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'不能   由于地址过滤器不匹配而在接收器处理   EndpointDispatcher。检查发件人和收件人   EndpointAddresses同意。

7 个答案:

答案 0 :(得分:10)

您是否尝试过WCF SvcConfigEditor?它可以从Visual Studio的“工具”菜单中获得。使用SvcConfigEditor打开您的web / app.config以获得有关正确操作的GUI帮助。

答案 1 :(得分:5)

看看this SO question

编辑:由于您没有为服务指定地址,请尝试点击: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 :(得分:1)

您正在使用WebInvokeAttribute默认情况下告诉WCF接受POST作为动词。由于您尝试通过GET操作访问它,因此会被忽略。

改为使用WebGetAttribute

每个MSDN:

  

如果您希望服务操作响应GET,请使用   相反,WebGetAttribute。

答案 3 :(得分:1)

我个人不喜欢WCF提供的所有配置选项(我ranted about it before),在您的情况下,您根本不需要使用配置。对于返回JSON的简单服务,您可以使用服务主机工厂,并且可以使用服务主机工厂,并且正是这样做(设置webHttpBinding / webHttp行为端点), System.ServiceModel.Activation.WebServiceHostFactory。在您的情况下,您可以:

  • 从配置中删除所有内容(实际上,您根本不需要配置)
  • 更新.svc文件以引用该工厂(见下文)

就是这样。这是.svc应该是什么样子:

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

还有一件事:我注意到您的课程没有使用[ServiceContract]进行修饰,但您在课程中的方法中有[WebGet]属性。如果界面(IZombieService)是用[ServiceContract]装饰的界面,那么界面中的方法应该是用[WebGet]装饰的方法。您也可以完全绕过界面并使用`[ServiceContract]装饰ZombieService

[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; }
}

答案 4 :(得分:0)

只使用ASP.NET Web API而不是WCF

答案 5 :(得分:0)

我正在使用.net框架4,VS2010。 我在global.asax.cs中犯了一个虚假错误,而不是创建 WebServiceHostFactory 的实例 我通过intellSense打了 WebScriptServiceHostFactory 。结果我得到了同样的错误:

使用'UriTemplate'的端点不能与'System.ServiceModel.Description.WebScriptEnablingBehavior'一起使用。

我在global.asax.cs中将实例更正为 WebServiceHostFactory ,我再也看不到错误了。

答案 6 :(得分:0)

WebGetWebInvoke指定您的BodyStyleWrappedRequest,然后移除UriTemplate。调用服务时使用函数名称。

希望它有所帮助。

示例:

    [OperationContract]
    [WebInvoke(Method = "POST",
        BodyStyle = WebMessageBodyStyle.WrappedRequest,
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json)]
    void register(string name, string surname);