8

我遇到了 WCF 配置问题。我有一个 WCF Web 服务,我希望能够使用 GET 参数通过 Web 浏览器访问它(最终在 PHP 中使用 simplexml_load_file())。我的 Visual Studio 解决方案设置为一个 WCF 服务库项目,其中包含一个接口(定义服务的位置)、一个类(实现服务的位置和一个 app.config(默认情况下)。我还有一个WCF 服务项目,其中包含一个 .svc 文件(指向我的类)和一个 web.config。我的服务接口设计如下:

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using RTXEngineLib.externalLibrary;
namespace RTXEngineLib {
    [ServiceContract(Name = "RTXEngine", Namespace = "")]
    public interface IRTXEngine {
        [OperationContract(Name = "GetCountryList"), WebGet(UriTemplate = "/GetCountryList/", ResponseFormat = WebMessageFormat.Xml)]
        List<Country> GetCountryList();
        [OperationContract(Name = "GetRegions"), WebGet(UriTemplate = "/GetRegions/?countryID={countryID}", ResponseFormat = WebMessageFormat.Xml)]
        List<Region> GetRegions(int countryID);
        [OperationContract(Name = "GetExchangeAvailability"), WebGet(UriTemplate = "/GetExchangeAvailability/?countryID={countryID}&month={month}&year={year}&regionID={regionID}&resortID={resortID}", ResponseFormat = WebMessageFormat.Xml)]
        AvailabilityList GetExchangeAvailability(int countryID, String month, int year, String regionID = "?", String resortID = "");
        [OperationContract(Name = "GetResortsForDate"), WebGet(UriTemplate = "/GetResortsForDate/?month={month}&year={year}", ResponseFormat = WebMessageFormat.Xml)]
        List<AvailabilityList> GetResortsForDate(String month, int year);
        [OperationContract(Name = "GetRegionLists"), WebGet(UriTemplate = "/GetRegionLists/", ResponseFormat = WebMessageFormat.Xml)]
        List<RegionList> GetRegionLists();
        [OperationContract(Name = "GetRegionListCacheState"), WebGet(UriTemplate = "/GetRegionListCacheState/", ResponseFormat = WebMessageFormat.Xml)]
        Boolean GetRegionListCacheState();
    }
    [DataContract(Namespace = "")]
    public class LoginRequestResponse {
        [DataMember]
        public Boolean Success { get; set; }
        [DataMember]
        public AccountStanding AccountStanding { get; set; }
        [DataMember]
        public double FTXBalance { get; set; }
        [DataMember]
        public List<User> Users { get; set; }
        [DataMember]
        public List<ContractData> Contracts { get; set; }
    }
    [DataContract(Namespace = "")]
    public enum AccountType {
        [DataMember]
        NonAuthenticatedAccount,
        [DataMember]
        AC,
        [DataMember]
        PT,
        [DataMember]
        Wks
    }
    [DataContract(Namespace = "")]
    public enum AccountStanding {
        [DataMember]
        NotAuthenticated,
        [DataMember]
        Good,
        [DataMember]
        Mixed,
        [DataMember]
        Delinquent
    }
    [DataContract(Namespace = "")]
    public struct RegionList {
        [DataMember]
        public String CountryName { get; set; }
        [DataMember]
        public String CountryID { get; set; }
        [DataMember]
        public List<Region> Regions { get; set; }
    }
    [DataContract(Namespace = "")]
    public struct Country {
        [DataMember]
        public String CountryName { get; set; }
        [DataMember]
        public String ID { get; set; }
    }
    [DataContract(Namespace = "")]
    public struct Region {
        [DataMember]
        public String RegionName { get; set; }
        [DataMember]
        public String ID { get; set; }
    }
    [DataContract(Namespace = "")]
    public struct User {
        [DataMember]
        public String FirstName { get; set; }
        [DataMember]
        public String LastName { get; set; }
        [DataMember]
        public String Address { get; set; }
        [DataMember]
        public String City { get; set; }
        [DataMember]
        public String State { get; set; }
        [DataMember]
        public String Zip { get; set; }
        [DataMember]
        public String CountryOfResidence { get; set; }
        [DataMember]
        public String PhoneNumber { get; set; }
    }
    [DataContract(Namespace = "")]
    public struct ContractData {
        [DataMember]
        public String ContractID { get; set; }
        [DataMember]
        public AccountType AccountType { get; set; }
        [DataMember]
        public AccountStanding AccountStanding { get; set; }
        [DataMember]
        public String AvailablePoints { get; set; }
        [DataMember]
        public String UnavailablePoints { get; set; }
        [DataMember]
        public String Usage { get; set; }
    }
    [DataContract(Namespace = "")]
    public struct PointsData {
        [DataMember]
        public String ContractID { get; set; }
    }
    [DataContract(Namespace = "")]
    public class GlobalAppCache {
        [DataMember]
        public static DateTime RegionListsLastUpdate { get; set; }
        [DataMember]
        public static List<RegionList> CachedRegionLists { get; set; }
    }
}

我的库的 App.config 如下所示:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5555555555555555">
      <section name="RTXEngineLib.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
    </sectionGroup>
  </configSections>
  <system.web>
    <compilation debug="true"/>
  </system.web>
  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <service name="RTXEngineLib.RTXEngineLib">
        <endpoint address="" binding="wsHttpBinding" contract="RTXEngineLib.IRTXEngineLib">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8732/Design_Time_Addresses/RTXEngineLib/RTXEngineLib/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <applicationSettings>
    <RTXEngineLib.Properties.Settings>
      <setting name="RTXEngineLib_externalLibrary" serializeAs="String">
        <value>http://externalLibrary.com/websvcs/externalLibrary.asmx</value>
      </setting>
    </RTXEngineLib.Properties.Settings>
  </applicationSettings>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

然后我的 Web.config 如下:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="Web" sendTimeout="00:03:00" maxBufferSize="131072"
          maxReceivedMessageSize="131072" />
      </webHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="Basic" name="RTXEngineLib.RTXEngineLib">
        <endpoint address="http://devrtxengine.telemark/RTXService.svc"
          binding="webHttpBinding" bindingConfiguration="Web" name="Basic"
          contract="RTXEngineLib.IRTXEngine" listenUri="http://devrtxengine.myserver/RTXService.svc" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
        <behavior name="Basic">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
        <behavior name="Web">
          <serviceMetadata httpGetEnabled="true" httpGetBinding="webHttpBinding"
            httpGetBindingConfiguration="" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>  
</configuration>

当我尝试使用运行我的服务http://devrtxengine.myserver/RTXService.svc/GetCountryList时,出现以下错误:

<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
<Code>
<Value>Sender</Value>
<Subcode>
<Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:DestinationUnreachable</Value>
</Subcode>
</Code>
<Reason>
<Text xml:lang="en-US">
The message with To 'http://devrtxengine.telemark/RTXService.svc/GetCountryList' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.
</Text>
</Reason>
</Fault>

我怀疑我的 App.config 和我的 Web.config 之间存在某种不匹配,但是每次我尝试更改 Web.config 中的某些内容时,我都会破坏我的服务,甚至超过它已经被破坏的程度。有更多 WCF 经验的人有什么建议吗?

4

2 回答 2

3

我注意到端点地址是 devrtxengine.telemark,但是您将 listenUri 作为 devrtxengine.myserver。不确定这是否是一个错字或是否会有所作为。此外,您可以尝试将 WebHttpBinding 添加到行为中 - 有关示例,请参阅Resolving Configuration Error in WCF AddressFilter Mismatch

于 2012-07-30T18:45:46.947 回答
2

这是我遇到该错误时检查的内容:

* endpoint is missing in web.config, 
* doublecheck the UriTemplate path
* make sure to set an endpointBehavior inside behaviors, such as 
  < endpointBehaviors >
    < behavior name =" web" >
      < webHttp />
    </ behavior >
  </ endpointBehaviors >
* and set behaviorConfiguration="web" on endpoint your individual endpoint
于 2013-10-04T19:25:13.233 回答