SharePoint 2010 hosted wcf and castle windsor - wcf

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" />

Related

Failed to add a service reference to WCF service

When attempting to add a service reference to a WCF service to my .NET project I am getting an error:
Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.
After doing some research I decided to add a metadate exchange endpoint to my service:
<endpoint
address="mex"
binding="mexHttpsBinding"
contract="IMetadataExchange"/>
Now, after adding the enedpoint I am getting a different type of error:
Could not find a base address that matches scheme http for the endpoint with binding BasicHttpBinding. Registered base address schemes are [https].
What am I doing wrong here?
If I open service in the browser, it works just fine:
https://alias.domain.com/ProjectName/MyService.svc?wsdl
mexHttpBinding is only for http:// but as your service is exposed over https:// you need to change it to mexHttpsBinding.
See here: https://msdn.microsoft.com/en-us/library/aa395212(v=vs.110).aspx
Solved!
The issue was that some XSD references in WSDL, schemaLocation in particular. For some reason schemaLocation used machine name instead of the domain name. After I fixed that I was able to add a reference to the service

Which protocol does WCF Test Client use (WcfTestClient.exe) to get metadata

According to my understanding metadata can be explored by using three types of bindings:
mexHttpBinding
mexHttpsBinding
mexTcpBinding
Are all these bindings supported by WcfTestClient.exe ?
UPD
According to my understanding alternative way to get metadata is get WSDL information (old way of posting metadata).
If EcfTestClient.exe supports all these bindings listed above it don't need WSDL. According to my understanding to enable WSDL I need to place <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" /> in web.config in behaviors. This is not required if metadata is retrieved using mexHttpBinding,mexHttpsBinding,mexTcpBinding bindings. Please, correct me if I'm wrong. In this case WcfTestClient.exe finds metadata.
If I do false for both httpGetEnabled and httpsGetEnabled WcfTestClient.exe can't get service info:
Error: Cannot obtain Metadata from http://localhost:35168/mySrv.svc 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.
Looks WcfTestClient.exe is getting information from WSDL and not from bindings mexHttpBinding , mexHttpsBinding , mexTcpBinding?
Well, based on MSDN, WCFTestClient supports all the bindings supported by SvcUtil. Now, if you look at the excerpts from MSDN below:
Svcutil issues the following metadata requests simultaneously to retrieve metadata.
MEX (WS-Transfer) request to the supplied address
MEX request to the supplied address with /mex appended
DISCO request (using the DiscoveryClientProtocol from ASMX) to the supplied address.
Looks like its safe to assume that WcfTestClient supports all three for metadata download.
MSDN WCFTestClient
MSDN SvcUtil

Custom binding element can't be loaded in WCF under IIS, however it can load under WCF Self-Host

I'm able to run the WCF-SecureProfile sample that comes with the MSFT WCF samples download (http://msdn.microsoft.com/en-us/library/ee818238.aspx)
However I can't port this server component to IIS. I get the error that
<MakeConnectionBindingElement/> can't be loaded. Considering that I have the behavior extensions loaded I don't know why IIS can't see the extension, however the self-host version of my app can.
I uploaded the sourcecode of the project into codeplex for easy browsing. Here is a direct link to web.config and all other files.
2
I got the sample and set it up to run on IIS local. I didn't get the same issue as the one in this question but I did run into a big gotcha. Accessing the service in IIS gave me this error message:
Contract requires Duplex, but Binding 'BasicHttpBinding' doesn't support it or isn't configured properly to support it.
After some head scratching, I found the cause of this issue. WCF 4 now assigns default bindings to each transport (I'm liking this feature less & less). For the HTTP transport, the default binding is basicHttpBinding. The problem is the customBinding config does not override any default binding. This causes WCF to attempt to configure duplex over basicHttpBinding which of course isn't supported. The fix is to turn off the default transport mapping for HTTP and assign it to your custom binding as shown below for this service:
<protocolMapping>
<clear/> <!-- removes all defaults which you may or may not want. -->
<!-- If not, use <remove scheme="http" /> -->
<add scheme="http" binding="customBinding" bindingConfiguration="rspBinding"/>
</protocolMapping>
Once I added this to the serviceModel element, the IIS based service worked just fine.

Consuming Web Service from 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.

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.