I have to connect to a legacy web service.
In visual studio, if I do a Add Service Reference, then enter the url of the WSDL file on server. My service shows up, and I write the code against it. But when I run the code I get this error:
System.ServiceModel.CommunicationException: The envelope version of
the incoming message (Soap12
(http://www.w3.org/2003/05/soap-envelope)) does not match that of the
encoder (Soap11 (http://schemas.xmlsoap.org/soap/envelope/)). Make
sure the binding is configured with the same version as the expected
messages.
My app.config looks like this:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="LoginServiceSoap" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://server/Service.asmx" binding="basicHttpBinding"
bindingConfiguration="LoginServiceSoap" contract="Stuff.Login.LoginServiceSoap"
name="LoginServiceSoap" />
</client>
</system.serviceModel>
However, I am able to communicate with the service fine, if I add a 'Web Reference'. But my understanding is that I am supposed to use Service References now, instead of WebReferences. I am assuming I have something wrong in my above config.
Or am I forced to use a Web Reference, because of the type of service I am connecting to?
Sheamus,
You could (theoretically) add the version number to the binding definition.
envelopeVersion="None/Soap11/Soap12"
With, of course, the right value for your service.
So it would look more like:
<basicHttpBinding>
<binding name="LoginServiceSoap"
envelopeVersion="Soap12" />
</basicHttpBinding>
Hope this helps you do things your way.
Related
I have a token issuer WCF service which is using Microsoft.IdentityModel (WIF 3.5) that I need to upgrade to System.IdentityModel (.NET 4.5). The problem is that I can't change the original name of the service , Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract, to it's newer counterpart, System.ServiceModel.Security.WSTrustServiceContract. For some reason it's not recognized by IntelliSense:
The blue squiggly line error is:
The 'name' attribute is invalid - The value 'System.ServiceModel.Security.WSTrustServiceContract' is invalid according to its datatype 'serviceNameType'
I do have assembly references to System.ServiceModel and System.IdentityModel in <assemblies> node.
Even when I ignore the IntelliSense error and run the service and access it using browser I'm getting this metadata error:
Metadata publishing for this service is currently disabled.
Metadata publishing is enabled so I think it's because of the name problem of the service.
Also I'm getting this error from the VS.NET WCF test client:
Error: Cannot obtain Metadata from http://localhost:49178/Services/Issuer.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. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.
WS-Metadata Exchange Error
URI: http://localhost:49178/Services/Issuer.svc
Metadata contains a reference that cannot be resolved: 'http://localhost:49178/Services/Issuer.svc'.
There was no endpoint listening at http://localhost:49178/Services/Issuer.svc 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.
HTTP GET Error
URI: http://localhost:49178/Services/Issuer.svc
The HTML document does not contain Web service discovery information.
I think the "Metadata contains a reference that cannot be resolved" line also refers to the service name resolve error.
Any ideas on what to do here? I'd appreciate any help..
Issuer.svc:
<%# ServiceHost Language="C#" Debug="true" Factory="Identity.Services.Wcf.Core.CustomSecurityTokenServiceContractFactory" Service="CustomSecurityTokenServiceConfiguration" %>
Factory:
public class CustomSecurityTokenServiceContractFactory : WSTrustServiceHostFactory
..
Service:
public class CustomSecurityTokenServiceConfiguration : SecurityTokenServiceConfiguration
..
Sometimes the best way to solve this kind of problems is to create a new WCF project from scratch, configure again your endpoints etc.. and copying over your existing services from your old project, this is especially true when moving from an older version of WCF.
Here is a checklist that I follow every time I have problems with WCF services:
The Server
Make sure your service contracts are defined using interfaces with the appropriate attributes, for example:
IMyService.cs
[ServiceContract]
public interface IMyService
{
[OperationContract]
int ThisAnOperation(int a, int b);
}
Check that you have implemented your contracts using the right interface:
MyService.cs
public class MyService: IMyService
{
public int ThisAnOperation(int a, int b)
{
return a * b;
}
}
You need to have a service host to access your service, they are the files with the extension .svc:
Create a file myService.svc.
Add the following line of code, referencing the class implementing your service:
<%# ServiceHost Language="C#" Debug="true" Service="YourNamespace.MyService" CodeBehind="MyService.cs" %>
Finally, you need to set up a binding which will define which transports and protocols are available to access your server, start with a simple basic HTTP binding to check that your service is working as expected, then change it to something more production ready that includes authentication and/or encryption and compression as needed.
To setup basic HTTP binding:
Remove the block <system.serviceModel>...</system.serviceModel> from your file web.config if it's already there.
Build your solution, it should compile successfully, otherwise fix any error and try again.
Right-click your web.config file and then click on "Edit WCF Configuration", then click on "Create a New Service" and in Service type, browse and choose the DLL file generated when you compiled your service (should be in the bin folder) and select the service class you would like to publish:
Specify the contract for the service (should be automatically filled up).
In the next page select the transport protocol for your service, in this case, "HTTP", then select "Basic Web Services interoperability".
In the next page you can specify the address for the endpoint, for testing purposes, you can leave this field empty (make sure you also remove "HTTP" from the text field).
Click next, close the configuration window and save.
Now you should be able to run the service and browse to MyService.svc to access your service.
Activate metadata publishing so your service can be found, to do this, add the following behavior to your web.config:
<system.serviceModel>
<services>
<service name="WcfService1.MyService">
<endpoint binding="basicHttpBinding"
bindingConfiguration="" contract="WcfService1.IMyService"
BehaviorConfiguration="MyServiceBehaviors" />
</service>
</services>
</system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehaviors" >
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
Now you should be able to run your project and get a metadata description page of your service within the browser, this info can be used by clients to find the service and generate a proxy of the service:
The Client
Delete any existing service references from your project.
Right click on your project name then in "Add Service Reference", input your service address and click on "Go", if everything went all right you should see your service in the Service Window:
Try to generate the proxy by finishing the wizard, rebuild your project and try it. If you still have the same problem, delete the generated reference and repeat points 1 and 2 and then:
Click on "Advanced" and uncheck "Reuse types in referenced assemblies":
Then finish the wizard and compile.
Hopefully, everything should work now!!!
I may have a similar setup as yours. In my case, I have both the STS and a service that is called by whoever wants a token. This is what you have, right?
In the Web.config for the actual STS I have:
<bindings>
<ws2007HttpBinding>
<binding name="ws2007HttpBindingConfiguration">
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false" clientCredentialType="Certificate"/>
</security>
</binding>
</ws2007HttpBinding>
</bindings>
<services>
<service name="System.ServiceModel.Security.WSTrustServiceContract" behaviorConfiguration="STSBehavior">
<endpoint address="IWSTrust13" binding="ws2007HttpBinding" bindingConfiguration="ws2007HttpBindingConfiguration" contract="System.ServiceModel.Security.IWSTrust13SyncContract" name="STSWCF"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
</service>
</services>
And in the Web.config for the service I have:
<protocolMapping>
<!-- We want to use ws2007FederationHttpBinding over HTTPS -->
<add scheme="https" binding="ws2007FederationHttpBinding" bindingConfiguration="ws2007FederationHttpBindingConfiguration"/>
</protocolMapping>
<bindings>
<ws2007FederationHttpBinding>
<binding name="ws2007FederationHttpBindingConfiguration">
<!-- We expect a bearer token sent through an HTTPS channel -->
<security mode="TransportWithMessageCredential">
<message establishSecurityContext="false">
<issuerMetadata address="https://localhost/Identity.STS.WCF/Service.svc/mex"/>
</message>
</security>
</binding>
</ws2007FederationHttpBinding>
</bindings>
<services>
<service name="Identity.Auth.WCF.Service" behaviorConfiguration="STSBehavior">
<endpoint address="https://localhost/Identity.Auth.WCF/Service.svc" binding="ws2007FederationHttpBinding" bindingConfiguration="ws2007FederationHttpBindingConfiguration" contract="Identity.Auth.WCF.IService" name="Identity.Auth.WCF"/>
</service>
</services>
Also, it does work for me here, even though I do get the same IntelliSense error as you, and in the very same spot.
My WCF service hang randomly. when I try to debug using Microsoft Service Trace Viewer I found out I was getting
The socket connection was aborted. This could be caused by an error
processing your message or a receive timeout being exceeded by the
remote host, or an underlying network resource issue. Local socket
timeout was '00:01:00'.
Therefore I change the "receiveTimeout" in the Net pipe binding section (server side) like this.
Server side
<netNamedPipeBinding>
<binding name="myPipeBinding"
receiveTimeout="24:0:0">
</binding>
</netNamedPipeBinding>
And then I try to update the config file of the client using the Visual Studio 2013 "Update Service Reference". It give me the new App.config in the client side like this.
<bindings>
<netNamedPipeBinding>
<binding name="NamedPipedService" />
</netNamedPipeBinding>
</bindings>
<client>
<endpoint address="net.pipe://localhost/Server" binding="netNamedPipeBinding"
bindingConfiguration="NamedPipedService" contract="WCFService.IServer"
name="NamedPipedService">
<identity>
<userPrincipalName value="Server\MyComputer" />
</identity>
</endpoint>
</client>
I thought everything work but my service crash again with the same error. So I thought "receiveTimeout" section of the "netNamedPipeBinding" should also be added in the client's App.config file. My question is
Is the error I am getting due to default timeout value of Net pipe binding?
Should I set the receiveTimeout value (server side) ?
Do I also need to change the App.config file in the client side for the changes to take effect? Since updating by Visual Studio 2013 does not add the receiveTimeout section.
I am pretty new to WCF and I was hoping someone could point me in the right direction.
Basically, I am trying to pull information from an existing WCF which was not developed by me.
So, for testing purposes, I created a console application and added the svc as a service reference.
I create a new instance of the client, and whenever I try to execute any of the methods, I get the following error:
The HTTP request was forbidden with client authentication scheme 'Anonymous'.
Does this mean the WCF requires a signed certificate to authenticate the client?
If this is the case, do I need to request/provide anything from/to the WCF's provider?
I´ve looked through several post related to this issue, but all these scenarios are based on the assumption that you have access to the server.
EDIT
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="..." />
<binding name="SecureByTransport">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/Web/ConnectWcf.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ConnectBasic"
contract="ConnectBasic.IConnectBasic" name="BasicHttpBinding_IConnectBasic" />
<endpoint address="https://localhost/Web/ConnectBasicWcf.svc"
binding="basicHttpBinding" bindingConfiguration="SecureByTransport"
contract="ConnectBasic.IConnectBasic" name="SecureByTransport" />
</client>
</system.serviceModel>
</configuration>
Im consuming some webservice from a third-party product.
So ive add righ-clicking on service reference and generating the code on the web.config file.
But the problem is, foreach company i consume the service, they have one endpoint address (and they have more then 30 companies). So, its insane to add one reference foreach company (to execute the same method in these webservices).
So, i would like to know if it is possible and how can i do a WebServiceHelper class, with some GetWebService(url) method wich allows me send just the url of the webservice and create my service model.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ITestService" receiveTimeout="10:00:00"
sendTimeout="10:00:00" maxReceivedMessageSize="2147483647" transferMode="Buffered"
useDefaultWebProxy="true" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://xxxx.xxx"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ITestService"
contract="Test.TESTSOAP" name="BasicHttpBinding_ITestService" />
</client>
We should be able to create a c# file from WSDL, same way as SVCUTIL does and then use reflection to create a proxy at run time.
Please follow through this article and download the source code provided.
DynamicProxyFactory
I created WCF service and testing WCF client using stand alone application. I was able to view this service using Internet Explorer also able to view in Visual studio service references. Here is the error message.
"The content type text/html; charset=UTF-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8)."
Could you please advice what could be wrong?
Thank you.
Since the returned content type is text/html, I suspect your call result in a server-side error outside of WCF (you are receiving an HTML error page).
Try viewing the response with a web debugging proxy such as Fiddler.
(Edit based on comments) :
Based on your comments, I see that your WCF is hosted under Sharepoint 2010, in a form-authenticated site.
The error you are receiving is due to the fact that your your WCF client is NOT authenticated with sharepoint -- it does not have a valid authentication cookie. Sharepoint then return an HTTP Redirect to an html page (the login.aspx page); which is not expected by your WCF client.
To go further you will have to obtain an authentication cookie from Sharepoint (see Authentication Web Service) and pass it to your WCF client.
(Updated edit) :
Mistake: The site is using claim based authentication.
Although this is not necessarily due to cookies or form authentication, the explaination of the provided error message remain the same. An authentication problem cause a redirection to an HTML page, which is not handled by the WCF client.
This may be helpful, check the url rewrite rules in ISS 7. This issue will occur if is you didn't configure rule properly.
It sounds like your application is expecting XML but is receiving plain text. What type of object are you passing in?
text/html is SOAP 1.1 header and Content-Type: application/soap+xml is SOAP 1.2
Verify your bindings and return header.
It should be same either 1.1 or 1.2
Add the following code to the web.config server project
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBinding_IService">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="Service">
<endpoint address="" name="BasicHttpBinding_IService"
binding="basicHttpBinding"
bindingConfiguration="basicHttpBinding_IService"
contract="IService" />
</service>
then update client web service,After the update, the following changes are made web.config
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<endpoint address="https://www.mywebsite.com/Service.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService"
contract="Service.IService" name="BasicHttpBinding_IService" />
I hope to be useful
i was getting this error in NavitaireProvider while calling BookingCommit service (WCF Service Reference)
so, when we get cached proxy object then it will also retrived old SigninToken which still may not be persisted
so that not able to authenticate
so as a solution i called Logon Service when i get this exception to retrieve new Token