I am receiving 404s when executing a WCF method on IIS6 when wildcard mapping is enabled.
You can all reproduce this by creating a new WCF Service in VS2008 (new Project > WCF Service Application). Browse to the dummy method ('GetData')... you will notice it returns 400... that's fine because it shows it's still forwarding to WCF.
However: if you enable wildcard mapping in IIS6 you will now get a 404, meaning WCF is no longer intercepting the request.
My code is as follows:
[ServiceContract]
public interface IRest {
[OperationContract]
[WebGet(UriTemplate = "/test")]
int Test();
}
With the following web.config:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="ServiceX.RestBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="ServiceX.RestBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" />
<services>
<service behaviorConfiguration="ServiceX.RestBehavior"
name="ServiceX.Rest">
<endpoint address="" behaviorConfiguration="ServiceX.RestBehavior"
binding="webHttpBinding" contract="ServiceX.IRest" />
</service>
</services>
</system.serviceModel>
All works fine without wildcard mapping; I can browse to '/services/rest.svc/test' and I'll receive the expected result.
However, as soon as I enable wildcard mapping (.* > C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll), then I start receiving 404s when I attempt to access a method (although I can still view '/services/rest.svc').
I've exhausted Google and StackOverflow :(
I just had the same problem with a WCF service running on IIS6.
I could browse the service on http://someurl/service.svc, but I would get a 404 when hitting a method on the service such as http://someurl/service.svc/somemethod.
The fix, in my case, was easy. The .svc file type was configured in IIS to be handled by C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll, but my service was running in a ASP.NET v4.0 apppool, so I simply pointed the .svc file type to be handled by C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll
Related
Okay I've created a WCF which I have tested in in IIS and works correctly.
There is a website running, and I've done the following to add this service to that domain:
-Copied the WCF DLL into the website's bin folder.
-Also copied all the DLL this service uses. (Just Newtonsoft.Json)
-Created a new .svc with the following line:
<%# ServiceHost Language="C#" Debug="true" Service="wcfOnScore.OnScoreQuery"%>
-And also added the following to the website's web.config file:
<System.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="WithDebug">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpBinding" scheme="http" />
</protocolMapping>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0" />
<services>
<service name="wcfOnScore.OnScoreQuery">
<endpoint address="http://www.onscore.co.za/OnScoreQuery.svc"
binding="basicHttpBinding"
listenUri="/"
contract="wcfOnScore.IOnScoreQuery" />
</service>
</services>
</system.serviceModel>
Now this seems to be working. I get the following page when I open it in the browser:
Link To The Screenshot
It is however, not working sadly. I am trying to consume this service from a c# Xamarin android application. It is supposed to return a JSON string. And does this fine when it is hosted locally - This leads me to believe the problem is not in the WCF but the way I am trying to host it.
Anything I might have missed? Or any other alternatives?
Thanks in advance people.
EDIT:
Thought I'd include the error.
"System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation."
The is what the completed eventhandler arguments returns.
Well this an answer to why I get the error, not really a solution. (Yet)
I commented out the Newtonsof.Json using statement. And put in a simple text return which worked.
So from this I deduce that the WCF code can't get its hands on the json.dll.
So it looks like all the above was done correctly if you would like to use as reference. (Except that .dll off course).
If you are trying to return JSON first test it on browser. Your service is SOAP based service because you are using basicHttpBinding. To get result on browser change the binding to WebHttpBinding and add following in your web config.
<endpointBehaviors>
<behavior name="RestBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
If you are able to get response on the browser, you will get response through android also.
I have set up a wcf service and when I browse to the .svc file I am presented with a screen that says...
You have created a service.
So I know that the service is running successfully. However I have looked in the configuration and it does not actually have an address.
<system.serviceModel>
<services>
<service behaviorConfiguration="CountryProvinceBehavior" name="CountryProvinceWCFService">
<endpoint address="" binding="webHttpBinding" contract="ICountryProvinceWCFService" behaviorConfiguration="CountryProvinceBehavior"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="CountryProvinceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="CountryProvinceBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
I then wrote a console app to test the service.
I got thr url from the browser and added a 'Service Reference' from a console application I was expecting the project to create enpoint defintions in my configuration file. And then when I create a client I could load up one of these configs but they aren't there....
You don't have to specify the address in configuration, although in this case you do specify the address for the endpoint (""). That means that WCF will use it as an address relative to the service base address. If the service is hosted in IIS, then it'll be the address of the .svc file. If the service is self-hosted (i.e., using ServiceHost directly), then the address will be the one passed to the ServiceHost constructor.
I have a WCF 4 service project that I created using the WCF REST Service Template 40.
My goal is to expose a single WCF service out as both a SOAP endpoint and a RESTful endpoint that returns JSON formatted data. Both endpoints must be protected via my DotNetOpenAuth OAuthAuthorizationManager that is copied from the sample project.
Thusfar, I have a SOAP WCF services that can successfully authorize a consumer from my OAuth service provider. To do this I used the same config that was in the DotNetOpenAuth Service Provider example.
Now, I am trying to setup a WCF RESTful JSON response endpoint for the same service and also secure that endpoint. I am unsure how to accomplish this. My initial idea was to make it look like this:
<behaviors>
<serviceBehaviors>
<behavior name="DataApiBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceAuthorization principalPermissionMode="Custom" serviceAuthorizationManagerType="OAuthServiceProvider.Core.OAuthAuthorizationManager, OAuthServiceProvider" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="DataApiBehavior" name="OAuthServices.DataApi">
<endpoint address="soap" binding="wsHttpBinding" contract="OAuthServices.Interfaces.IDataApi"/>
<endpoint address="json" binding="webHttpBinding" contract="OAuthServices.Interfaces.IDataApi"/>
</service>
</services>
And then I saw this blog post about making RESTful WCF services + DotNetOpenAuth work together:
http://www.theleagueofpaul.com/codesnippet-ooo-openid-odata-oauth-together
I am not sure if setting up a Factory plus the ServiceAuthorization section of the service config would cause problems.
I am also unsure if there is anything I need to do in the RegisterRoutes method in the Global.asax:
private void RegisterRoutes()
{
RouteTable.Routes.Add(new ServiceRoute("DataApi", new WebServiceHostFactory(), typeof(DataApi)));
}
Any advice here would be appreciated. Thanks for any assistance.
Please let me know if you need more information.
Not sure, but I've heard that to enable SOAP you need to use basicHttpBinding and set
aspNetCompatibilityEnabled="true"
I could be wrong, but why not try?
I created simple wcf service with default functionality and hosted in IIS7. Its working fine and rendering data to the client. But when I try to click on wsdl link in the service its showing "Page cannot be displayed".Let me know what will be the problem
.
When I try to click the link below (http://win-nsms.smsserver.com/VirtualFolder/MyService.svc?wsdl), WSDL file is not getting displayed in the browser. Instead I am getting "The page cannot be displayed" error in the page
Now If I change the "win-nsms.smsserver.com" to "localhost" in the URL, WSDL file is getting displayed.
Yes I added behaviour configuration in my config as follows
<system.serviceModel>
<services>
<service name="WcfServiceSample.Service1" behaviorConfiguration="WcfServiceSample.Service1Behavior">
<endpoint address="" binding="wsHttpBinding" contract="WcfServiceSample.IService1">
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://win-nsms.smsserver.com"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
<behaviors>
<serviceBehaviors>
<behavior name="WcfServiceSample.Service1Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
Have you allowed retrieval of service meta data?
In the behaviours section of your config file, add a new behaviour like this:
<behaviors>
<serviceBehaviors>
<behavior name="HttpGetMetadata">
<serviceMetadata httpGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
Then tell your service to use this behaviour:
<system.serviceModel>
<services>
<service name="MyService"
behaviorConfiguration="HttpGetMetadata">
....
This is telling your service to allow the service metadata (the WSDL) to be retrieved via http. To confirm you can browse to the appropriate URL.
Is "mymachinename.domainname.com" added as a hostmask in IIS for the site?
You may need to setup the base address for the service.
<serviceHostingEnvironment>
<baseAddressPrefixFilters>
<add prefix="http://mymachinename.domainname.com"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
I had a similar problem where the service was working 100% for domain.com but not www.domain.com. I had to setup the latter as a redirect to the former and set the base address to the former.
HTH!
Did you enable WDS exposure? Standard settings dont show the WDSL.
I'm having a couple of issues which may be related, or may not. I noticed that when I use Add Service Reference in Visual Studio to add a reference to my data service, the reference.cs it generates does not compile. It complains about a missing namespace. I can fix it up to compile, but this happens every time I update the reference, and it's worrying on other levels too, such as "will this cause other issues".
I also noticed that when I do this, my host server (a console application hosting the data service) logs this:
An exception occurred [System.Data.Services.DataServiceException] :: The URL
representing the root of the service only supports GET requests.
This is the service config:
<service behaviorConfiguration="behaviour" name="StatsPlus.Server.HostedServices.SPDataServiceHost">
<endpoint address="svc" binding="webHttpBinding" contract="System.Data.Services.IRequestHandler" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8752/DataService/"/>
</baseAddresses>
</host>
</service>
And the behaviour:
<behavior name="behaviour">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="10"/>
</behavior>
When I try to run svcutil http://localhost:8752/DataService/, I get this:
HTTP GET Error
URI: http://localhost:8752/DataService
There was an error downloading 'http://localhost:8752/DataService'.
The request failed with HTTP status 405: Method Not Allowed.
Any ideas? Much appreciated
Thanks
I think you're connecting to a wrong address. You have a base address
<add baseAddress="http://localhost:8752/DataService/"/>
and on top of that a relative endpoint address
<endpoint address="svc" binding="webHttpBinding"
so your complete URL will be the combination of the two:
http://localhost:8752/DataService/svc
Did you try to connect there??
I am not sure if you can have a "mex" metadata exchange endpoint with WCF REST services, really. I was under the impression that the client-side proxy for a WCF Data Service gets its metadata over a special URL call from the HTTP endpoint. So maybe try to remove that from your config as well (and you can't use svcutil on that service, I believe - svcutil is only for SOAP service calls, if I'm not mistaken).
Also, since you're using webHttpBinding and self-hosting, you need to add the webHttp behavior:
<behavior name="behaviour">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="10"/>
<webHttp />
</behavior>
If you do these two steps, I think you should be able to get at your WCF Data Service. Try it and let us know!