Should the WSDl only be accessible via the ".svc?wsdl" ? I have a service that has multiple endpoints. For example (in the web.config):
<services>
<service behaviorConfiguration="MyServiceTypeBehavior" name="WcfService1.Service">
<endpoint binding="wsHttpBinding" bindingConfiguration="ws1"
name="ws1" contract="WcfService1.IMyService" />
<endpoint address="http://www.blah.com/Service.svc/Basic" binding="basicHttpBinding"
bindingConfiguration="Basic" name="Basic" contract="WcfService1.IMyService" />
<endpoint address="http://localhost:5606/Service.svc/Secured"
binding="wsHttpBinding" bindingConfiguration="WsSecured" name="WsSecured"
contract="WcfService1.IMyService" />
</service>
</services>
If I go to: http://www.blah.com/Service.svc/Basic I get a 404 page error. When I go to http://www.blah.com/Service.svc?wsdl I see my wsdl and my 3 endpoints at the bottom of the page. Should I be able to get to the other endpoints via their address? I have a client that is using Axis2 to get to our services and I would like to use multiple endpoints for different clients. I know that I can add this to the serivce behavior:
<behavior name="MyServiceTypeBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="Basic" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
</behavior>
But I would have to create a service entry for each endpoint, right? Should I even be concerned about being able to access the endpoints via a URL?
Thanks
Daniel
I think you might be over-thinking this. The WSDL will specify all endpoints and their policies. Clients can specify which endpoint to use for communication.
You don't need to navigate to the URL of the endpoint.
Related
I have a test WCF service that I hosted on IIS. I added a new application to the default website and used default app pool to host my test service. I am able to browse the .svc file from the content view in IIS and the success page along with a link to wsdl opens up on Windows IE. However, on clicking the wsdl link, a HTTP 404(Not found) error is thrown.(everything is on my localhost being accessed internally)
I have added the metadata endpoint and this is the relevant portion of my web.config file.
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="mexBehaviour" name="ClassLibrary1.HelloWorldService">
<endpoint address="HelloService" binding="basicHttpBinding" bindingConfiguration=""
contract="ClassLibrary1.IHelloWorldService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:17000"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
Can someone please guide me about what I can be missing? Could it be a permissions issue or anything else?
Thanks.
There is no need to add the base address to service contract which will be provided by the IIS web server.
The default wcf application configuration enable the service metadata and we are able to access the metadata by the svc page or we directly use the following url.
http://localhost:90/Service1.svc?wsdl
Feel free to contract me If the problem still exists.
I'm creating a WCF4 service with REST and SOAP endpoints to be hosted in IIS 7.5.
I have used the WCF4 REST template as an example.
However I have a few questions regarding my setup so far.
Here's my webconfig
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<behaviors>
<endpointBehaviors>
<behavior name="REST">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="MEXGET">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MEXGET" name="Project.WebService.VehicleService">
<endpoint
address=""
behaviorConfiguration="REST"
binding="webHttpBinding"
contract="Project.WebService.IVehicleService" />
<endpoint
address="soap"
binding="basicHttpBinding"
contract="Project.WebService.IVehicleService" />
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
I have removed the standardEndpoints section and added endpoints of my own.
There are no .svc files as I've set the routes in the global.asax as shown below
private void RegisterRoutes()
{
RouteTable.Routes.Add(new ServiceRoute("VehicleService", new WebServiceHostFactory(), typeof(VehicleService)));
}
The help pages can be accessed via http://localhost:1313/ServiceTest/VehicleService/help
I've also used the WCF Test Client to access http://localhost:1313/ServiceTest/VehicleService/mex
which shows the metadata for the SOAP endpoint
But how do I retrieve the WSDL of the service?
With an svc file I can find the wsdl at http://localhost:1313/ServiceTest/VehicleService.svc?wsdl However I do not have a .svc file.
And neither can I find the WSDL at http://localhost:1313/ServiceTest/VehicleService?wsdl or http://localhost:1313/ServiceTest/VehicleService/soap?wsdl
Do I need to add a .svc file if I want to publish WSDL for the SOAP endpoint?
I have managed to get the WSDL working at http://localhost:1313/ServiceTest/VehicleService?wsdl.
The solution was using new ServiceHostFactory instead of new WebServiceHostFactory in the global.asax.
With WebServiceHostFactory you lose the WSDL functionality.
A similar question can be found here:
ServiceRoute + WebServiceHostFactory kills WSDL generation? How to create extensionless WCF service with ?wsdl
You should be able to get the WSDL by using the mex URL directly from the browser:
http://localhost:1313/ServiceTest/VehicleService/mex
The WcfTestClient is almost certainly doing that to retrieve the WSDL so it can generate the proxy to the service.
I am trying to create a WCF service that is accessible through both webHttpBinding and netTcpBinding. I have been successful in getting the webHttpBinding to be accessible through a Java client and now I'm working on trying to get the netTcpBinding working.
I have set up the configuration like this;
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="httpBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<services>
<service name="MR_Jukebox_Service.JukeboxService">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8732/Design_Time_Addresses/MR_Jukebox_Service/"/>
<add baseAddress="net.tcp://localhost:8523/Design_Time_Addresses/MR_Jukebox_Service/net/"/>
</baseAddresses>
</host>
<endpoint address=""
behaviorConfiguration="httpBehavior"
binding="webHttpBinding"
contract="MR_Jukebox_Service.IJukeboxService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="MR_Jukebox_Service.IJukeboxService" />
<endpoint address="net.tcp://localhost:8523/Design_Time_Addresses/MR_Jukebox_Service/net"
binding="netTcpBinding"
bindingConfiguration=""
contract="MR_Jukebox_Service.IJukeboxService" />
</service>
</services>
</system.serviceModel>
In the same solution, I have a test application that I wish to connect to the netTcpBinding, I've right clicked on "Service References" and chosen "Add Service Reference...".
When I click on "Discover" it finds the service although says;
There was an error downloading 'http://localhost:8732/Design_Time_Addresses/MR_Jukebox_Service'.
The request failed with HTTP status 404: Not Found.
Metadata contains a reference that cannot be resolved: 'http://localhost:8732/Design_Time_Addresses/MR_Jukebox_Service'.
There was no endpoint listening at http://localhost:8732/Design_Time_Addresses/MR_Jukebox_Service that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
The remote server returned an error: (404) Not Found.
If the service is defined in the current solution, try building the solution and adding the service reference again.
But I am also unable to see the netTcpBinding in order for me to create a service reference to it.
I was wondering whether anyone can see what I am doing wrong as its probably something rather simple, but due to my lack of experience with WCF haven't noticed.
Thanks for any help in advance.
Try changing your mex endpoint to this:
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
You were using your service's contract for the mex endpoint, which I don't believe will work.
You can set up a similar one for the NetTcpBinding:
<endpoint address="net.tcp://localhost:8523/Design_Time_Addresses/MR_Jukebox_Service/net/mex"
binding="mexTcpBinding"
contract="IMetadataExchange" />
I have been successful in getting the webHttpBinding to be accessible through a Java client and now I'm working on trying to get the netTcpBinding working.
Are you trying to get the netTcpBinding to work with a java client ? Because, netTcpBinding only works with a .net client.
NetTcpBinding is not designed for interop, it's designed for performance when both the server and client are .net
I have two websites hosted on the same IIS server. SiteA contains WCF services that need to be accessed by SiteB, as well as anything else that is authenticated on the domain.
The service is configured with a wsHttpBinding and thus I believe uses Windows security by default. Right now I can call the services from a console app running on my local machine, as well as from a web application running in the default Visual Studio web server, so I am taking that the authentication is working.
However, when SiteB tries to access the services, it fails with this error:
The caller was not authenticated by the service.
SiteB runs on the same machine than SiteA so I don't understand why it could not be authenticated. SiteB uses Forms Authentication and I mapped Anonymous access to a domain user.
Here are the config bits:
SiteA (service):
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service behaviorConfiguration="wcfServiceBehaviour" name="MyService">
<endpoint address="" binding="wsHttpBinding" contract="IServiceContract" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="wcfServiceBehaviour">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
SiteB (client):
<system.serviceModel>
<client>
<endpoint address="http://xxxxx/Services/xxService.svc"
binding="wsHttpBinding"
contract="IServiceContract" />
</client>
</system.serviceModel>
You are correct - wsHttpBinding configured in WCF will use Windows Authentication by default.
There is a suggestion here - WCF - changing endpoint address results in securityexception - that the Identity block will not work with Windows Authentication - try removing it.
When SiteB impersonates another user, does your code specify the impersonation level?
My guess is that your are not specifying a high enough level of impersonation. (Delegation is the highest, allowing SiteB to pass the permissions to a different service).
I suspect that fixing up the SiteB impersonation code will be enough to solve the problem.
If not, try passing the allowable impersonation level to the server:
<system.serviceModel>
<client>
<endpoint address="http://xxxxx/Services/xxService.svc"
binding="wsHttpBinding"
contract="IServiceContract"
behaviorConfiguration = "ImpersonationBehavior" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="ImpersonationBehavior">
<clientCredentials>
<windows allowedImpersonationLevel = "Delegation" /> <!-- The highest level -->
</clientCredentials>
</behavior>
<endpointBehaviors>
</behaviors>
</system.serviceModel>
If you're using a self hosted site like me, the way to avoid this problem (as described above) is to stipulate on both the host and client side that the wsHttpBinding security mode = NONE.
When creating the binding, both on the client and the host, you can use this code:
Dim binding as System.ServiceModel.WSHttpBinding
binding= New System.ServiceModel.WSHttpBinding(System.ServiceModel.SecurityMode.None)
or
System.ServiceModel.WSHttpBinding binding
binding = new System.ServiceModel.WSHttpBinding(System.ServiceModel.SecurityMode.None);
Is it possible to use the new WCF routing serice in WCF 4 for REST based services? I have something similar to a reverse proxy in mind. Basically I have a number of selfhosted rest based serivces which I want to expose via IIS with the same base url and port. The routing should be done by the last part of the url. I'm absolutly new to thw WCF routing service, so forgive me if that's a silly question, but I couldn't find any information about that on the web.
I have tried something like this (where serivce1/2 are the selfhosted services):
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="RoutingBehavior">
<routing routeOnHeadersOnly="false" filterTableName="RoutingTable"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="RoutingBehavior" name="System.ServiceModel.Routing.RoutingService">
<endpoint address="myservices" contract="System.ServiceModel.Routing.IRequestReplyRouter" binding="basicHttpBinding"/>
</service>
</services>
<routing>
<filterTables>
<filterTable name="RoutingTable">
<add filterName="service1Filter" priority="0" endpointName="service1"/>
<add filterName="service2Filter" priority="0" endpointName="service2"/>
</filterTable>
</filterTables>
<filters>
<filter name="service1Filter" filterType="MatchAll"/>
<filter name="service2Filter" filterType="MatchAll"/>
</filters>
</routing>
<client>
<endpoint address="http://somehost:8888/test/service1" binding="basicHttpBinding" contract="*" name="service1"/>
<endpoint address="http://somehost:8732/test/service2" binding="basicHttpBinding" contract="*" name="service2"/>
</client>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
but that doesn't seem to work. I'm getting an endpoint not found exception. http://somehost:8888/test/service1 ist the base address of the selfhosted service and not the actual endpoint. Can I do routing based on the base address or (if rest routing is possible) must I add a route for every endpoint?
I solved the problem by using a reverse proxy (in my case arr). I don't konw if using the WCF routing service for this purpose is possible, but it's probably a misuse.
Routing Service is only available for SOAP requests. To use routing with RESTful WCF you need to setup your routes using System.Web.Routing similar to MVC routing.