WCF 配置地狱?

Posted

技术标签:

【中文标题】WCF 配置地狱?【英文标题】:WCF Configuration Hell? 【发布时间】:2011-10-25 04:21:04 【问题描述】:

我讨厌带有端点、行为等的 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' 不能 由于 AddressFilter 不匹配,在接收方处理 端点调度程序。检查发送方和接收方的 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' 不能 由于 AddressFilter 不匹配,在接收方处理 端点调度程序。检查发送方和接收方的 EndpointAddresses 同意。

【问题讨论】:

什么都没拉?您能否尝试发布一些有用的内容,或者包括一个问题? 查看 WCF 4.0 - 它解决了很多的配置难题!阅读A Developer's Intro to WCF 4了解更多详情。 【参考方案1】:

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

【讨论】:

【参考方案2】:

看看this SO question。

编辑:由于您没有为服务指定地址,请尝试点击:http://localhost:22059/ZombieService.svc/KnownZombies(使用 .svc)。

我还认为您需要将 &lt;webHttp /&gt; 行为添加到您指定的端点行为中。

编辑:尝试将您的端点定义更改为:

<service 
  name="HighOnCodingWebApps.ZombieService"
  behaviorConfiguration="MyServiceTypeBehaviors">

  <endpoint 
    address="" 
    binding="webHttpBinding"
    behaviorConfiguration="SomeBehavior"
    bindingConfiguration="default"
    contract="HighOnCodingWebApps.IZombieService" />

</service>

【讨论】:

【参考方案3】:

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

请改用WebGetAttribute。

每个 MSDN:

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

【讨论】:

我把它改成了下面的 [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "KnownZombies")] public Zombie GetZombie() return new Zombie() Name = "Mohammad Azam"; 但结果相同【参考方案4】:

我个人不喜欢 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 class

[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】:

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

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

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

【讨论】:

有一个标签用于启用 WebScript 但不是用于禁用它,因此您会认为不添加该标签会禁用它。但是只有当我添加了清除标签时它才得到解决: 【参考方案6】:

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

【讨论】:

+1 取消反对票。 WCF 非常不适合将一些 JSON 内容返回到 HTTP 请求的任务,如果您使用真正适合该任务的工具,一切都会变得非常简单。 虽然这可能是个好建议,但它不是问题的答案。当你写一个答案时,弹出的小窗口特别说要避免根据意见发表声明。【参考方案7】:

在您的WebGetWebInvoke 中将您的BodyStyle 指定为WrappedRequest,然后删除UriTemplate。调用服务时使用函数名。

希望对你有帮助。

例子:

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

【讨论】:

以上是关于WCF 配置地狱?的主要内容,如果未能解决你的问题,请参考以下文章

什么是地狱回调?解决回调地狱的两种方法

回调地狱以及用promise怎么解决回调地狱

CTF实战(隐写术):欢迎来到地狱

promise解决回调地狱

解决回调地狱问题

基于PROMISE解决回调地狱问题