Consuming Web Service from WCF - wcf

I have created a WCF service, now this WCF service has to call a Web Service. What I am doing is adding the service reference of web service in WCF and calling the method of the web service which I want to use.
Just an example shown below :
CalcWebReference.CalculatorSoapClient fct =
new CalcWebReference.CalculatorSoapClient();
int rq = fct.Add(q, r);
return rq;
Now this method when I tried to call from the client it is giving following error
The server was unable to process the
request due to an internal error. For
more information about the error,
either turn on
IncludeExceptionDetailInFaults (either
from ServiceBehaviorAttribute or from
the configuration
behavior) on the server in order to
send the exception information back to
the client, or turn on tracing as per
the Microsoft .NET Framework 3.0 SDK
documentation and inspect the server
trace logs.
Thanks i did what u told but now i am getting following error "Could not find default endpoint element that references contract 'CalcWebReference.CalculatorSoap' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element."
Now do i need to give some end points in the WCF service or in the web service to get the function from web service and if so then how do i give it.
Please help.
Hi,
CalcWebReference.CalculatorSoapClient is reffering to the web service not WCF.
Given below is the code written in WCF(sample code) which is calling the web service :-
CalcWebReference.CalculatorSoapClient fct = new CalcWebReference.CalculatorSoapClient();
int rq = fct.Add(12, 10);
return rq;
Am i not putting the syntax right or is there any additional thing that i need to do in this?

This is the generic WCF "something bad happened" error message. That won't really be much help.
Approaches:
make sure the web service you're calling works on its own - otherwise fix it!
enable the detailed error information, as described in the error message, by including the error details in your WCF service (do this in DEV environments only! Never in production...)
try to launch your WCF service inside Visual Studio and debug what's happening
In order to enable detailed error reporting, you need to add this section to your WCF service's configuration:
<behaviors>
<serviceBehaviors>
<behavior name="DebugBehavior">
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
You might already have a service behavior configured - in that case, just add the <serviceDebug> tag to your service behavior.
If you don't have a service config yet - you'll also need to make sure your service actually uses that service config:
<service name="YourServiceNameHere"
behaviorConfiguration="DebugBehavior">
Make sure to have a behaviorConfiguration= attribute on your <service> tag, and make sure to reference that defined service behavior (by specifying its <behavior name="..." > property).
Once you've done that, your error should hopefully give you more information - you should definitely get an .InnerException on your exception that should point you in the right direction.

Related

SharePoint 2010 hosted wcf and castle windsor

I am trying to work out how to host a wcf service in sharepoint 2010 which uses castle windsor. I can host my own standard custom web service without any issues by using one of the service factories from http://msdn.microsoft.com/en-us/library/ff521586(v=office.14).aspx.
Setting up a normal wcf service with castle windsor involves modifying the global.asax but, as this is not recommended for SharePoint, I have created an HttpModule which sets up the container and I have updated the web config to use it by creating a feature reciever.
My problem is where to go next. I am using the MultipleBaseAddressBasicHttpBindingServiceHostFactory for my service because that dynamically configures all of the endpoints for the service based on the IIS configuration but in order to use castle windsor it looks like it is necessary to change to using the supplied Castle.Facilities.WcfIntegration.WindsorServiceHostFactory. I have tried just switching over to see what happens but that does not seem to work. I get the following error
Error: Cannot obtain Metadata from <svc url> If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error URI: <svcurl> Metadata contains a reference that cannot be resolved: '<svcurl>'. The requested service, '<svcurl>' could not be activated. See the server's diagnostic trace logs for more information.HTTP GET Error URI: <svcurl> There was an error downloading '<svcurl>'. The request failed with HTTP status 404: Not Found.
I assume this is because I haven't configured an endpoint for the service but the few examples I have seen online do not seem to either.
Has anyone managed to get castle windsor and sharepoint wcf working - preferably with dynamic configuration if possible?
The error message that you are getting is that the metadata of the service is not published. To do this you need 2 things:
A mex endpoint for your service:
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
And service meta data turned on in service behavior:
<serviceMetadata httpGetEnabled="True" />

serviceDebug includeExceptionDetailInFaults="true" - On live site

I am using a WCF service that sits under an ASP.NET website.
I want to keep service debug / exeption details on when I go live as it is convenient for catching errors in the global.asax file without having to throw fault exceptions.
<serviceDebug includeExceptionDetailInFaults="true" />
Is there any reason why I should not do this. I have an error handler in place in the ASP.NET site.
You will expose internal details to the client - and that can of course be considered a security issue. But if you control the client(s) and trust on your error handling on the ASP.NET site maybe that is not the case for you. The SOAP messages will also be larger.
I think it's generally considered a bad idea leave it on in production.

Changing the publicly exposed endpoint URL for a WCF web service without changing the site bindings

I have a WCF web service hosted in IIS7 which is reporting its endpoint URL as the following in its WSDL
http://machinename/virtualdirectory/service.svc
However the actual public URL which clients need to use is actually
http://machinename.mydomain.com/virtualdirectory/service.svc
And so at the moment clients that attempt to use this web service fail unless they manually edit the endpoint URL.
I know that I can fix this by changing the bindings of the site in IIS as per HOWTO: Fix WCF Host Name on IIS however in this case the site is shared with another application which stops working if I do this and so this isn't an option.
Is there another way that I can change the endpoint URL that WCF uses for this one virtual directory?
Although not directly answering my question (how can I set the WSDL endpoint URL in the web.config file) adding the <useRequestHeadersForMetadataAddress /> element to the <serviceBehaviors> section of my web.config file did fix my problems as now the endpoint URL is based on the URL used to access the WSDL, which is always the same as the URL used to call the web service.
Note that in this SO question it indicated that I needed to supply port numbers, note that this wasn't necessary for me - just adding the <useRequestHeadersForMetadataAddress /> element was enough
<serviceBehaviors>
<behavior name="<name>">
<!-- Other options would go here -->
<useRequestHeadersForMetadataAddress />
</behavior>
</serviceBehaviors>
There are a couple of options depending on which version of WCF your service is using. If you're using .NET 4 or higher, look at the accepted answer to this SO question. Otherwise you can either apply the hotfix that question references or if you're really desperate, hack the metadata URL of the httpGetUrl attribut to point to a copy of the WSDL which has been manually edited to contain the desired endpoint URL.

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;

404 BadRequest exposing WCF service through external IP using IIS host headers

We host a WCF webservice on Windows Server 2003. This server only has 2 internal IP's. We want to expose the service externally. This is done through the firewall that maps an external IP to the service.
So, I would need to modify the service to display that external IP for the internal links. This is not an issue since it should only be used externally.
Changing the Host Header value in IIS gives a 'Bad Request (Invalid Hostname)' response from IIS. I also added an 'address' value to the endpoint entry in the web.config ... but it sill just points to the internal machine name. Any ideas?
edit: I can verify that IIS7 has the exact same behaviour. Address didn't work. Different hostname gave Invalid Hostname error. Is there seriously no way to present a different (fictive) IP? :/
edit2:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicAnonymous">
<security mode="None"/>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="Extended">
<serviceMetadata httpGetEnabled="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483646"/>
</behavior>
</serviceBehaviors>
</behaviors>
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="false" logMessagesAtServiceLevel="false" logMessagesAtTransportLevel="true" maxMessagesToLog="3000"/>
</diagnostics>
<services>
<service behaviorConfiguration="Extended" name="AnCWCFWebService.ProductInfoProvider">
<endpoint address="" binding="basicHttpBinding" name="ASMX" bindingConfiguration="BasicAnonymous" contract="AnCWCFWebService.Interfaces.IProductInfoProvider"/>
</service>
</services>
</system.serviceModel>
404 BadRequest Due to IIS Configuration...
If you are receiving a 404 BadRequest error from IIS after attempting to modify host headers in IIS, this is common, but there is a fix!
Fix By Making IIS Configuration Changes
How can WCF support multiple IIS Binding specified per site?
Fix By Making WCF Code Modifications
Alternatively, the following article explains how one developer solved this issue with a combination of configuration and code:
Well, that was fun! An adventure in WCF, SSL, and Host Headers
http://geekswithblogs.net/rakker/archive/2008/07/03/123562.aspx
The article references two important links...
The first one explains how to properly set the host headers in IIS:
Configuring Server Bindings for SSL Host Headers (IIS 6.0): http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/8d9f2a8f-cd23-448c-b2c7-f4e87b9e2d2c.mspx?mfr=true
After getting host headers working, you'll find that...
"you can't have more than one host
header for IIS or wcf will break"
The solution to working around this limitation is found within this article, and there is also a comment on the GeeksWithBlogs.net article above that provides an enhanced variation:
WCF: This collection already contains
an address with scheme http
If you are still experiencing trouble, let us know in the comments below...
If the Service is Not Working...
My experience with WCF is that it is very tricky at times, especially with configuration. If one is following best practices and not doing anything non-standard, the great majority of deployment problems are the result of a botched configuration file.
In theory (not so much in practice, due to architectural differences), setting up a WCF service on IIS should be no different than setting up a typical virtual directory and corresponding application for web application or for an ASMX web service.
Therefore, I recommend that if this is the first WCF service you are exposing to the Internet, follow the same simple approach you would take when exposing your first website. Basically, create a new sample "WCF Service Application" (this is available in the Add New Project dialog, under the Web section of C# or VB).
Once you have it working, follow your deployment practices to move it into a production sandbox and test it locally. This sandbox would preferably already have some web sites or web services installed and known to be accessible from the Internet, in order to eliminate any doubt about the typical network configuration issues. If you have a sample ASMX web service that is already successfully exposed on the Internet from that server, that would be best.
Next, try testing the the ASMX and the WCF services from web browser, both locally on the server, internally on other desktops and then finally externally.
Testing URLs
We want to test accessing the standard SVC and ASMX file from the web browser in all the varieties of URL flavors that are available and relevant. The results should be similar, with summary page about he service rendering in the window. The difference will be that the ASMX web service's summary will likely allow you to execute the web methods on the service if that feature has not been disabled in the web.config file.
Compare the results of browser fetches of the following styles of URLs...
http://localhost/WcfService1/Service1.svc
http://localhost/WcfService1/Service1.asmx
http://MachineName or MachineFQN/WcfService1/Service1.svc
http://MachineName or MachineFQN/WcfService1/Service1.asmx
http://MachineLocalIP#1/WcfService1/Service1.svc
http://MachineLocalIP#1/WcfService1/Service1.asmx
http://MachineLocalIP#2/WcfService1/Service1.svc
http://MachineLocalIP#2/WcfService1/Service1.asmx
http://ExternalIP/WcfService1/Service1.svc
http://ExternalIP/WcfService1/Service1.asmx
All of these tests should return similar results.
Testing Service Methods
If you feel like it, go head and test some web methods on the ASMX web service for any of the tested URLs, from the web browser. You'll soon see that we can test ASMX web services a different way also...
Next we'll test web methods on both the WCF service and the ASMX web service by using the WcfTestClient.exe application that is found in the Visual Studio 2008 distribution (C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE).
You will need to add the services through the File->Add Service menu item, typing in the URL above for each service URL that you wish to test. Make sure to include the filename of the SVC and ASMX files. If all is well, the MEX endpoint that is enabled by the "httpGetEnabled" attribute of the <serviceMetadata/> element in the web.config file will return the data that is necessary for the utility to operate, thereby populating the tree with the inventory of our service methods like this:
From this point, it will be useful to refer to the following to resources:
WCFTestClient: http://msdn.microsoft.com/en-us/library/bb552364.aspx
What's New for WCF in Visual Studio 2008: http://msdn.microsoft.com/en-us/magazine/cc163289.aspx
Conclusion
If you make it this far, then I do not expect any other issues and you should now attempt to compare the setup of the samples to the WCF service that you are attempting to publish to the Internet, and hopefully the differences will be obvious.
Remember to treat the WCF service like an ASMX web service during you diagnostics, assuming that the web.config is known to be set up correctly.
If you are still unable to make things work, check this guide for further technical advice:
Deploying an IIS-hosted WCF service: http://msdn.microsoft.com/en-us/library/aa751792.aspx
Finally, if all else fails, just wrap your WCF service in an ASMX web service:
How to: Expose WCF service also as ASMX web-service: http://kjellsj.blogspot.com/2006/12/how-to-expose-wcf-service-also-as-asmx.html
You just need to configure your host header in the IIS so that the links in the WSDL references will use the donmain name rather local machine name.
Check out
Steps to configure IIS host header so that WCF will use domain name in WSDL references.
Why not just assign a new IP address to the server instead of messing around with hostnames? A Windows Server can have multiple IP addresses for the same NIC.
Here is an article that talks about it.