I am having WCF configuration woes. I have a WCF Webservice that I want to be able to access through a web browser using GET parameters (and eventually in PHP with simplexml_load_file()). My Visual Studio Solution is set up as a WCF Service Library project containing an Interface (where the service is defined), a class (where the service is implemented, and an app.config (which was there by default). I also have a WCF Service Project which contains a .svc file (which points to my class) and a web.config. My Service Interface is designed like this:
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}®ionID={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; }
}
}
And my App.config for the library looks like this:
<?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>
And then my Web.config is as follows:
<?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>
When I attempt to run my service using http://devrtxengine.myserver/RTXService.svc/GetCountryList
I end up with the following error:
<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>
I suspect that there is some kind of mismatch between my App.config and my Web.config, but every time I try to change something in my Web.config I break my service even more than it is already broken. Does anyone with more WCF experience have any advice?
I noticed that the endpoint adress was devrtxengine.telemark, but you have the listenUri as devrtxengine.myserver. Not sure if that's a typo or if it would make a difference. Also, you can try adding the WebHttpBinding to the behaviors - see Resolving Configuration Error in WCF AddressFilter Mismatch for an example.