WCF base address not found - wcf

My service can work with normal WCF calls, but to expose metadata (the wsdl file) I have to change configuration in such a way the normal WCF host fails.
I've spend countless hours on google trying to solve this, big problem there is that hosting a service inside a website is never discussed (yes this is different).
requirements:
Runs in an existing web site
Use sessions
Operable with Java, and as much .net versions as possible.
Expose metadata (wsdl will be enough)
edits:
IIS cannot be used
I'm using .NET 4 and WCF 4.
In this configuration the metadata can be reached (through the wsdl file) but when trying to host the normal wcf endpoints I get and InvalidOperationException:
Could not find a base address that matches scheme http for the endpoint with binding WSHttpBinding. Registered base address schemes are [].
So the base address is ignored.
But when I supply full addresses to the endpoints (simply copy the base address in front of the current address) the normal WCF calls work fine, but when trying to access metadata I get the following error:
No protocol binding matches the given address 'http://localhost:8080/Functionality'.
Protocol bindings are configured at the Site level in IIS or WAS configuration.
Here is the web.config serviceModel section, I made a small test web site just for testing this, but it would be to much to post all of it here, if you send me a pm though I will e-mail it to you.
<system.serviceModel>
<services>
<service behaviorConfiguration="metadataSupport" name="MyStuff.TestWithMetadata">
<endpoint address="Functionality" binding="wsHttpBinding" name="FunctionalityBinding"
contract="MyStuff.ITestWithMetadata" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="metadataSupport">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="metadataSupport">
<!--Navigate with browser to httpGetUrl for the wsdl file-->
<serviceMetadata httpGetEnabled="true" httpGetUrl="Metadata" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false">
<serviceActivations>
<add relativeAddress="TestWithMetadata.svc" service="MyStuff.TestWithMetadata" />
</serviceActivations>
</serviceHostingEnvironment>
</system.serviceModel>
If anyone has any ideas on how to solve this, please help out.

When you host your service in IIS (which I assume from your requirement "Runs in an existing web site"), then your base address in the config is moot - it will not be used at all.
When hosting in IIS, your service address is determined by:
your server name
possibly a port number
the virtual directory (and possibly subdirectories thereof) where the *.svc file lives
the *.svc file itself (including extension)
So it might be something like:
http://MyServer:7777/ExistingWebApp/TestWithMetadata.svc
or whatever it is that you have in your case.
You seem to be using .NET 4 and WCF 4 (never mentioned that.....) and in that case, you could skip the *.svc file altogether by adapting your config entry:
<serviceHostingEnvironment multipleSiteBindingsEnabled="false">
<serviceActivations>
<add relativeAddress="MyService" service="MyStuff.TestWithMetadata" />
</serviceActivations>
</serviceHostingEnvironment>
In this case, the value of relativeAddress= becomes the service address (within the virtual directory this web.config lives in) - so your service address would be something like:
http://MyServer:7777/ExistingWebApp/MyService
No need for a *.svc file at all in this situation.

Turned out I should use httpGetUrl link to get the metadata, instead of the .svc file, with that the base address can be ignored.
I also moved this test stuff to the actual web site and got tons of problems with zero endpoints being loaded. That was caused by the service reference in serviceActivations not set to the full service name (needs to have namespace included).
I accepted marc's answer because he did help me along and to prevent this question from popping up in unanswered.

Related

WCF: relativeAddress,baseAddress and binding

I am new in WCF and start my experience with a simple file-less application part of which (web.config) you can see below:
<serviceHostingEnvironment multipleSiteBindingsEnabled="true">
<serviceActivations>
<add
factory="System.ServiceModel.Activation.ServiceHostFactory"
relativeAddress="./RelativeAddress.svc"
service="WCF_Transactions.MyService1"/>
</serviceActivations>
</serviceHostingEnvironment>
Now I can access service at
http://localhost:18148/RelativeAddress.svc
Then I add next lines:
<services>
<service name="WCF_Transactions.MyService1" behaviorConfiguration="MyBehavior1">
<host>
<baseAddresses>
<add baseAddress="http://localhost:18148/" />
</baseAddresses>
</host>
<endpoint address="/RelativeAddressX.svc" binding="basicHttpBinding" contract="WCF_Transactions.IService1"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyBehavior1">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
So I expect that my service could be accessible through next address:
http://localhost:18148/RelativeAddressX.svc
but I can't do this. What have I misunderstood?
MSDN http://msdn.microsoft.com/en-us/library/ms733749.aspx:
*
There are two ways to specify endpoint addresses for a service in WCF.
You can specify an absolute address for each endpoint associated with
the service or you can provide a base address for the ServiceHost of a
service and then specify an address for each endpoint associated with
this service that is defined relative to this base address. You can
use each of these procedures to specify the endpoint addresses for a
service in either configuration or code. If you do not specify a
relative address, the service uses the base address.
*
So according to your example you have base adress
http://localhost:18148/
and it will be combined with RelativeAddress.svc, as a name of your svc file. And then it will try to combine this string with /RelativeAddressX.svc as a part of endpoint adress. So you will have something like
http://localhost:18148/RelativeAddress.svc/RelativeAddressX.svc.
Your endpoint must not specify the path to svc in IIS. It should containg only a logical adress, assosiated with this point.
So try to change your endpoint to the following:
<endpoint address="RelativeAddressX" binding="basicHttpBinding" contract="WCF_Transactions.IService1"></endpoint>
And it should be accessible by the path
http://localhost:18148/RelativeAddress.svc/RelativeAddressX
You don't need to specify in the config file when hosting in IIS or Cassini - the base URL is provided by the web server. The element is used when self-hosting. Cassini (VS build in web-server) will ignore it.
Here is a good page about WCF addressing:
http://msdn.microsoft.com/en-us/magazine/cc163412.aspx
Here are some related posts:
WCF Service Endpoints vs Host Base address
WCF, changing the baseAdress of an endpoint

Simplest Console Hosted WCF Service generates a 404 when browse to it

I have the very simplest Console based host for a simple WCF service. The app config for the service is:
<system.serviceModel>
<services>
<service name="MagicEightBallServiceLib.MagicEightBallService"
behaviorConfiguration="EightBallServiceMEXBehavior">
<endpoint address=""
binding = "basicHttpBinding"
contract = "MagicEightBallServiceLib.IEightBall" />
<!-- Enable the MEX endpoint-->
<endpoint address="mex"
binding ="mexHttpBinding"
contract ="IMetadataExchange" />
<!--Need to add this so MEX knows the address of our service -->
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/MagicEightBallService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="EightBallServiceMEXBehavior">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
The host program shows its running perfectly:
** Console Based WCF Host *
***** Host Info ******
Address: http://localhost:8080/MagicEightBallService
Binding: BasicHttpBinding
Contract: IEightBall
Address: http://localhost:8080/MagicEightBallService/mex
Binding: MetadataExchangeHttpBinding
Contract: IMetadataExchange
**************************************************
The service is ready
When I attempt to browse to or generate a proxy I get:
HTTP Error 404.0 - Not Found
I can't figure out what's wrong. You can't get any simpler than this!
I have faced the same problem when reading Troelsen's book and could not find any answer online. Anyway it seems that the problem is in the project type for MagicEightBallLib. Troelsen suggests that you create a Visual C# -> Windows -> Class Library project, but he does not explain what modifications you need to make for it to work. If you instead use the Visual C# -> WCF -> WCF Service Library project, it will automatically start the WcfTestClient.exe, and add new tab in project's Preferences called "WCF Options". I tried to compare the differences between .csproj files for both types of projects but there is just too many.
So the solution is to just start with the WCF Service Library project type instead of Class Library, and adjust names of interfaces and classes so they fit what is in the book.
If anyone knows which particular parts of the .csproj file are responsible for enabling this, I'd very much like to hear about it.
Hope this helps.
Instead of using localhost:8080 use 127.0.0.1:8080. That's how I got the example to work on my windows 10 machine.

Problem with WCF Hosting on Mono

I am trying to host a simple application with one .aspx, .asmx and .svc file each. I followed the below guide to achieve the hosting (since I am very new to the linux world, it took a while to understand it!):
http://www.mono-project.com/Mod_mono#Manual_Mod_Mono_Configuration
After all the hosting, I am able to access the aspx and asmx file. But when I try to access the svc file, I get the below error:
The ServiceHost must have at least one application endpoint (that does not include metadata exchange endpoint) defined by either configuration, behaviors or call to AddServiceEndpoint methods.
or
HttpListenerContext does not match any of the registered channels
I do have a pretty straight forward service endpoint defined in my web.config which looks like below:
<system.serviceModel>
<services>
<service name="TestWCFService">
<endpoint address="http://localhost/MonoTest/TestWCFService.svc" binding="basicHttpBinding"
contract="MonoTest.ITestWCFService"></endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
Can you please tell me what I am doing wrong?
Note: I used MS VS 2010 to create this project and then published it. The published directory is copied to the Apache/Linux Environment. The WCF doesn't make use of any complex type. I am using Mono Version 2.8.2
UPDATE
Update: I tried using 2.10.2 Mono. This error is gone and I am now facing a new one:
XmlSchema error: Named item http://tempuri.org/:DoWork was already contained in the schema object table. Consider setting MONO_STRICT_MS_COMPLIANT to 'yes' to mimic MS implementation. Related schema item SourceUri: , Line 0, Position 0.
After weeks of R&D on this I have figured out this. For some reason, I can't get the service WSDL to work (meaning I can't access the .svc from browser). However, the service works fine when I try to access it using Channel Factory.
So I have implemented everything in Channel Factory (for my Silverlight app) and everything seems to be working fine right now. I am still not sure how to get WSDL to work but that's not too important to me as of now.

WCF endpoints, baseAddressPrefixFilters, host headers

I have two websites on the same machine. The first (client) references a WCF service on the second site(server).
How do I set the address for the service reference? When moving from development on my local machine to the group development server, how do I change the url for the service? The sites are differentiated by host headers, like
http://dev.admin/...
and
http://dev.public/...
I sense that this can be handled using multiple endpoints, but I'm very new to WCF and really don't have a clue what I'm doing here.
After much frustration, I managed to determine that both web.config files (on the client and server, both of which are web apps in this case), the following sections have to be changed:
Client:
<client>
<endpoint
address="http://mysite.com:port/services/someservice.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_ISomeService"
contract="MyServices.ISomeService"
name="BasicHttpBinding_ISomeService" />
</client>
</system.serviceModel>
Server
<system.serviceModel>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://mysite.com:port/services"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior name="MyServices.SomeServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyServices.SomeServiceBehavior"
name="MyServices.SomeService">
<endpoint address="http://mysite.com:port/services/someservice.svc"
name="endpoint.SomeService"
binding="basicHttpBinding"
bindingConfiguration=""
contract="MyServices.ISomeService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
The thing to note here is that the host address in all three relevant sections (client endpoint address, server baseAddressPrefixFilter value, and server endpoint address) have to match.
I'm able to switch between servers by modifying these, as long as they match. I would still prefer a way to set this based on which machine the server is running on, but this works for the moment.
WCF Impressions
What's hot: persistent object. The client proxy object (created when you add a service reference) maintains a persistent connection to the service on the server. The service instance referenced by the client proxy maintains its state between calls, which can simplify method signatures and makes the client proxy object, and the service as a whole, much more useful for certain applications. Parameter object types can be shared between the client and server if they're declared in a common library, meaning that you don't have to create two very similar classes or wrapper classes to pass non-primitive data structures back and forth.
What's not: configuration is a royal pain, poorly documented, and far too involved. Getting this to work in a test/dev/staging/production environment configuration where the service neesd to be aware of its location is frustrating. I'm not convinced that making the service aware of its domain url (rather than, say, a relative path to whatever it's running on) has any significant benefit, security concerns aside.
That said, I'm continuing to go down the WCF path as the advantages thus-far outweigh the headaches.
Easiest way: run the WCF parts on different ports.

WCF cannot find base address for http using REST service

I'm seeing the following error coming from WCF when trying to hit my REST WCF service on IIS 6.0:
Could not find a base address that matches scheme http for the endpoint with binding WebHttpBinding. Registered base address schemes are [].
My web.config looks like:
<system.serviceModel>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<!--LOCAL-->
<add prefix="http://localhost/CustomTrackingService/CustomTrackingService.svc"/>
<!--TEST-->
<!--<add prefix="http://mytestserver/CustomTrackingService/CustomTrackingService.svc"/>-->
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<services>
<service name="MyService.CustomTrackingService">
<endpoint
address="MyAction"
binding="webHttpBinding"
contract="MyContract.ICustomTrackingService"
behaviorConfiguration="RestBehavior" />
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="RestBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
This works fine on my test server and works fine locally if I let Casini grab it (change base address prefix localhost/CustomTrackingService to localhost:1234/). I cannot remember what causes this to occur and my Google-fu is not producing useful results. Any ideas?
So looks like the problem is that locally i was trying to use a relative address with no base address defined. This worked on my test server because the test server incorrectly had more than one host header defined, which seems to translate into more than one base address defined in WCF, which is a no-no. i originally used the on the test server because i was getting an error about more than one base address for http, and without realizing the real problem, I filtered out the one I wanted using . Thsi won't work locally because I have no host headers defined, so the filter provided nothing and the relative addressing attempt failed because no base address was specified.
I'm going to do some more experimenting to see what the best set-up for my situation is, but checking the host headers in IIS definitely helped. Also, this link was a huge help in understanding what was really going on.
Why are you using a base address prefix + an unrelated value in endpoint#address if you're hosting in IIS?