WCF allows you to specify an external WSDL file that should be published with the service rather than WCF's generated WSDL. In a WSDL-first design approach, it makes a lot of sense to publish the source WSDL rather than the generated WSDL.
This is set using the externalMetadataLocation:
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" externalMetadataLocation="path_to_my_wsdl.wsdl"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
The problem I'm encountering is that when I do this, it serves the WSDL straight-up, which has the wrong endpoint address. I want the endpoint address to be replaced at run-time with the real endpoint address of the service (which will differ depending on where it is deployed).
Is there an easy way to do this?
I'm in no way a WCF expert but can't you do this by specifying it on the endpoint in the config file (web.config), for example:
<system.serviceModel>
<services>
<service>
<endpoint
listenUri="https://yourdomainname.com/servicename.svc"
address="https://yourdomainname.com/servicename.svc">
Note: "listenUri" is the physical address and the endpoint "address" is the logical address. Ie. "listenUri" is where the service really is and endpoint is what the client will be asking for.
If they are the same you don't need listenUri I believe.
Related
I am having trouble with my WCF service which somehow fails to expose/publish a WSDL definition. I have already gone through the MSDN tutorial on exporting Metadata. Also have I searched at least for some hours but the majority of people have different/simpler problems than me.
I am pretty sure my config file is correct so I would be thankful for anybody who could suggest other places I can look for?
My service is generally running and I can access it on localhost, where I get the standard page for the WCF services (message displaying "To test this service, you will need to create a client and use it to call the service. You can do this using the svcutil.exe tool from the command line with the following syntax:" etc.).
When I try to access the *?wsdl extension my browser tells me that the page couldn't be found.
When I try to test the service in soapUI it tells me that there is something wrong with the WSDL.
So, I hope this gives anybody an idea of what my problem is and I would be really thankful for any help.
Cheers
Have you specified httpGetEnabled in your serviceBehavior?
<behaviors>
<serviceBehaviors>
<behavior name="SubscriberOperationsBehavior">
<serviceMetadata httpGetEnabled="true"
httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
You can also create a mex endpoint.
Add the following endpoint to your service configuration:
<endpoint contract="IMetadataExchange" binding="mexHttpBinding" address="mex" />
I am writing a system where we do not want to expose the metadata on a WCF service. When setting up the service we get our clients to browse the .svc files in order to determine if they have hosted the service correctly.
Where does his page come from, is it an IIS contsruct? Is it generated by WCF?
Is it possible to replace the html page that comes up with our own custom html page?
httpHelpPageUrl lets you move the default WCF help page to another location from serviceDebug element. Make sure you turn off httpGetEnabled.
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false"
httpsHelpPageEnabled="true"
httpHelpPageEnabled="true"
httpHelpPageUrl="myhelpPage.html"
httpsHelpPageUrl="myhelpPage.html"/>
</behavior>
</serviceBehaviors>
</behaviors>
More information SO How can I change an html output of wcf service with my own content?
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.
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.
I'm modifying my WCF API to include a new service that should be exposed to internal IP addresses only. All of the services in my API are available in SOAP, POX and JSON. What I'm looking for is a behavior or something that allows me to implement a simple IP address filter, to process requests from internal IP's and deny everything else. I'd like it to work in configuration, because all the other services in the API should remain available to the Internet. I did some googling but can't find anything like this built into WCF. Am I missing something?
Ok, I figured it out, and its kind of slick, in my opinion.
I implemented an IP Filter system as a service behavior, then added it to my service in the web.config. Here's my new web config behaviors section:
<serviceBehaviors>
<behavior name="ServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
<behavior name="RestrictedServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<IPFilter filter="172.*.*.* 127.0.0.1" />
</behavior>
</serviceBehaviors>
The IPFilter class implements IDispatchMessageInspector to catch the request as soon as possible, inspect the client IP and throw an exception if it doesn't match the filter. If anyone's interested I can post my code.
If your service is hosted in IIS, then you can do this with IIS, on a per-website basis (maybe per-application, but I don't know).