What url is needed to consume WCF service - wcf

I have created a WCF service in Visual Studio 2010 and published it to a server running IIS 7.5.
It has one method - called returnNumber. This takes an int parameter called numberIn, multiplies it by 2 and returns the answer.
If I put
http://myserver/TestService/Service1.svc?wsdl
in a browser, it displays a page of XHTML.
What url should I use so that I can call my WCF service from a browser - passing a number in the QueryString so that the returnNumber method is called?
Further to responses below - Daniel - here is my code:
The web config:
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<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>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
</configuration>
An IServicer1.cs file containing an interface:
namespace NumberTest
{
[ServiceContract]
public interface IService1
{
[OperationContract(IsOneWay = false)]
int returnNumber(int numberIn);
}
}
And Service1.svc.cs
namespace NumberTest
{
public class NumberService : IService1
{
public int returnNumber(int numberIn)
{
int returnValue = numberIn * 2;
return returnValue;
}
}
I have published the above to
http://myServer/TestService
and, if I add a reference to the WCF service from within a VS Web Application, the returnNumber method is exposed and works if I call it.
How do I allow people running web sites that are not asp.net (so they cannot add a service reference) to be able to call my returnNumber method and get a number back?

To pass arguments to a service on the querystring you are unfortunately not using the correct technology stack.
WCF exposes web operations across a SOAP 1.2 (by default) endpoint, which means that the web server expects a SOAP request (that is a soap envelope wrapping the XML request payload) directed to the services URL.
What you want to do is hook up a pure HTTP web service, for which the correct Microsoft technology stack is ASP.NET WebApi.

You can use the WCF Test Client (depending on the version of VS you are using), pop in the address for your WSDL, and use that to test your web serivce.
If you use the test client and a tool such as Fiddler, you could find out the URLs that are being used under the covers by looking for HTTP POSTs to your web service.

Regarding your second question, consuming your web service from a non-asp.net platform, you should only need to configure your service to provide the WSDL.
Non-.net platforms, aka Java, have tools, such as wsdl2java, that consume the WSDL and produce the necessary client code.
The tools and usage will vary depending on platform, but the following link should provide a valuable point of reference. http://axis.apache.org/axis2/java/core/docs/userguide-creatingclients.html
Regards,

Related

Client config of WCF REST service is not being updated

I am using VS2012. My client configuration not updated when I have added service reference of WCF REST service. It is updating if I change binding to 'basicHttpBinding' in a WCF Service. Following is my WCF Service configuration.
<endpoint address="" binding="webHttpBinding" contract="MyService.IService1" behaviorConfiguration="RestBehavior">
<endpointBehaviors>
<behavior name="RestBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
My WCF service is split into following projects.
WCFHost(has only .svc file with web.config mentioned above and uses following two projs)
WCFInterfaces (Class library, has no config file)
WCFImplementaions (Class library, has no config files)
I wonder if I am doing anything wrong with decoupling of WCF layers above and hence my client app unable to get config details when Service reference added.
Visual Studio service reference does the magic because SOAP services provide WSDL. If you create a REST service, there is no WSDL and it will not work. The moment you switch to basic HTTP, it works because it is SOAP. You have to use HTTP libraries like HttpClient to talk to a REST endpoint.

How to access HttpContext.Current.User.Username in WCF service

How can I access HttpContext.Current.User.Username from a web application in a WCF service?
Generally you don't - HttpContext is an ASP.NET concept and doesn't apply to WCF unless you run it with ASP.NET Compatibility turned on.
If you want the current user in WCF then use ServiceSecurityContext.Current.PrimaryIdentity or get the security context via the OperationContext.
Actually, with Asp.Net Compatibility mode on, you can access HttpContext.Current.User from a WCF service hosted in the site. See Microsoft's site for details: https://msdn.microsoft.com/en-us/library/aa702682(v=vs.110).aspx
If your service is hosted in an Asp.net site you just need to update your web.config to set aspNetCompatibilityEnabled="true" on the serviceHostingEnvironment element:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>

Supply a different endpoint address in the WSDL of a WCF web service

I have a fairly standard WCF service (hosted on IIS7) which generates a fairly standard WSDL when queried with ?wsdl:
<wsdl:definitions>
<!-- ... -->
<wsdl:service>
<wsdl:port>
<soap:address location="https://machine/virtual_dir/servicename.svc"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
(boring bits omitted)
I'm after a quick 'n dirty way to change the address given in this generated WSDL to something completely different, for example:
https://othermachine/other_dir/other_service.svc
What is the easiest way of doing this?
There are several approaches you could look at:
WCF supports a lot of extensibility points, and the generation of the WSDL is one of those. You could write your own custom WSDL generator and plug it into WCF
the probably easier way would be to generate the WSDL you have, then tweak it manually, and put that WSDL file somewhere and configure it to be served up (instead of WCF generating the WSDL at runtime, when requested to do so)
You can configure option #2 with the <serviceMetadata> behavior:
<behaviors>
<serviceBehaviors>
<behavior name="StaticMetadata">
<serviceMetadata httpGetEnabled="true"
externalMetadataLocation="(url path to your static WSDL file)" />
</behavior>
</serviceBehaviors>
</behaviors>
If you do this, and your service uses this service behavior, any requests for the WSDL or for MEX data will be routed to that static WSDL you've provided, instead of using the auto-generated WSDL that WCF would normally supply.

WCF Service in ASP.NET application generating intermittent 404 errors

This problem has defeated my attempts at Google, so here goes. We were having an issue getting data from a WCF service (just lookup data, so we enabled it for HTTP GET requests). Every once in while it will return a 404. The stack trace does NOT appear to have WCF in the mix - the StaticFileHandler appears to be attempting to serve it.
I created a a sample WCF service on ASP.NET 3.5 SP1 and am able to reproduce the problem. This is my sample service - the only differences from stock WCF at this point are the AspNetCompatibilityRequirements and the enabling of WebScript and HTTP GET:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
public string DoWork(string param1)
{
System.Threading.Thread.Sleep(150);
return "bar";
}
}
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet]
string DoWork(string param1);
}
Service config:
<service name="namespace.Service1">
<endpoint
behaviorConfiguration="WebScriptEnabled"
address="http://localhost:2961/svc/Service1.svc"
binding="webHttpBinding"
contract="namespace.IService1">
</endpoint>
</service>
Behavior config:
<behaviors>
<endpointBehaviors>
<behavior name="WebScriptEnabled">
<enableWebScript />
</behavior>
</endpointBehaviors>
</behaviors>
My node has aspNetCompatibilityEnabled="true">, but otherwise everything is pretty much OOB. I have no customizations on webHttpBinding at all.
If I F5 on VS 2008 using the built in web server and hit the URL, the very first request will result in a 404. If I continue to hit it with even a light load (7-10 simultaneous requests), I'll get a handful of 404 errors.
If I then let the load drop down to nothing and rerun my test, I can go to 50 simultaneous requests easily WITHOUT any errors.
My real service is much more complicated than this, but the fact that I can get a (nearly) stock sample to show this behavior is concerning, as though there might be a framework related issue. I've enabled WCF diagnostics and tracing but nothing shows in the logs (not unexpected since WCF is not in the stack trace when the 404 occurs).
I hope I'm doing something wrong and have not discovered a framework bug. My production environment is IIS6 and appears to exhibit the same behavior as my development server.

How to get working path of a wcf application?

I want to get the working folder of a WCF application. How can I get it?
If I try
HttpContext.Current.Request.MapPath(HttpContext.Current.Request.ApplicationPath)
I get a null reference exception (the Http.Current object is null).
What I meant with the working folder was the folder where my WCF service is running. If I set aspNetCompatibilityEnabled="true", I get this error:
The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
I needed the same information for my IIS6 hosted WCF application and I found that this worked for me:
string apPath = System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;
As always, YMMV.
Please see ongle's answer below. It is much better than this one.
Updated after more information
The following worked for me. I tested it with a new WCF Service I hosted on IIS through a Service1.svc.
Add <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> to web config. <system.serviceModel>..</ ..> existed already.
Add AspNetCompatibilityRequirementsAttribute to the service with Mode Allowed.
Use HttpContext.Current.Server.MapPath("."); to get the root directory.
Below is the full code for the service class. I made no changes in the IService1 interface.
[AspNetCompatibilityRequirements(RequirementsMode=AspNetCompatibilityRequirementsMode.Allowed)]
public class Service1 : IService1
{
public void DoWork()
{
HttpContext.Current.Server.MapPath(".");
}
}
And below is an excerpt from the web.config.
<system.serviceModel>
<!-- Added only the one line below -->
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
<!-- Everything else was left intact -->
<behaviors>
<!-- ... -->
</behaviors>
<services>
<!-- ... -->
</services>
</system.serviceModel>
Old answer
What do you mean by the Working Folder? WCF services can be hosted in several different ways and with different endpoints so working folder is slightly ambiguous.
You can retrieve the normal "Working folder" with a call to Directory.GetCurrentDirectory().
HttpContext is an ASP.Net object. Even if WCF can be hosted on IIS, it's still not ASP.Net and for that reason most of the ASP.Net techniques do not work by default. OperationContext is the WCF's equivalent of HttpContext. The OperationContext contains information on the incoming request, outgoing response among other things.
Though the easiest way might be to run the service in ASP.Net compatibility mode by toggling it in the web.config. This should give you access to the ASP.Net HttpContext. It will limit you to the *HttpBindings and IIS hosting though. To toggle the compatibility mode, add the following to the web.config.
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
Depending on what you want. I usually want to resolve a url like "~/folder/file". This is what worked.
System.Web.Hosting.HostingEnvironment.MapPath("~/folder/file");
More general, I am using this one
AppDomain.CurrentDomain.BaseDirectory
The aspNetCompatibilityEnabled="true" should have resolved my problem, but I got this error:
The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
I resolved my problem with getting the physical path of my running WCF service by getting it from my current app domain:
AppDomain.CurrentDomain.BaseDirectory
In order to reference ASP.NET features like the HttpContext object, you need to run your WCF app in ASP.NET compatibility mode. This article explains how to do this.
Use HostingEnvironment.ApplicationPhysicalPath in WCF to find your application physical path.
Use namespace
using System.Web.Hosting;