My team and I have been working on this for the past several days but have not been able to resolve it. This is our query:
Three binding parameters, maxBufferPoolSize, maxBufferSize and maxReceivedMessageSize were included in basicHttpBinding configuration as below:
<basicHttpBinding>
<binding name="ABCBinding" maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
</binding>
</basicHttpBinding>
And included the binding in the endpoint configuration:
<service behaviorConfiguration="mexBehavior" name="XYZ">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="ABCBinding"
contract="ABC"/>
We have a really large input file which we send from Client which brought us to the issue in the first place. The file was getting sent only on the below cases:
1) The binding had no name.
2) In protocol mapping when the binding configuration was specified as below:
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
<add binding="basicHttpBinding" scheme="http" bindingConfiguration="ABCBinding" />
</protocolMapping>
What I doubt is that the Endpoint configuration is not taken at all. Because as stated https://learn.microsoft.com/en-us/dotnet/framework/wcf/simplified-configuration in this link-
If you do not add a "service" section or add any endpoints in a
"service" section and your service does not programmatically define
any endpoints, then a set of default endpoints are automatically added
to your service, one for each service base address and for each
contract implemented by your service.
To create default endpoints the service host must know what bindings
to use. These settings are specified in a "protocolMappings" section
within the "system.serviceModel" section. The "protocolMappings"
section contains a list of transport protocol schemes mapped to
binding types.
and
If no bindingConfiguration is specified, the anonymous binding
configuration of the appropriate binding type is used.
The configuration works when the binding name is removed or when the name is specified in protocol mapping.
So does this mean that the endpoint specified is not taken into consideration?
Please help me with this issue.
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.
I have created a new WCF project using Visual Studio 2012,
I noticed that there is no Service node in the web.config to define the service and the contract, however i deployed the service to azure and it worked, however I`m getting this error:
The remote server returned an unexpected response: (413) Request Entity Too Large. In Silverlight
so i guess i need to increase the maximum allowed request but how do i do that with no service node ?
Beginning with VS 2010 WCF added the concept of default endpoints (as well as default bindings and behaviors), to simplify configuration.
The details can be found at this link: A Developer's Introduction to Window's Communication Foundation 4
In your case, you'll need to create a binding in your config file that has larger sizes, and either set that as the default binding or assign that binding to an explicitly defined endpoint.
By default WCF (in .NET 4+) will assign request coming in over http to basicHttpBinding. These protocol mappings can also be changed in the config file.
A couple of simple examples to help you (the article I linked goes into more detail):
To create a default binding, simply define the binding and omit the name attribute:
<bindings>
<basicHttpBinding>
<binding maxReceivedMessageSize="10000000" ....>
</basicHttpBinding>
</bindings>
This will make your supplied configuration the default basicHttpBinding for the service(s) using that config.
Alternatively, you can use the name attribute on a binding configuration and then assign it to an defined input. Let's say you have a binding name "MyBinding":
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="MyBinding"
contract="MyService.IMyContract" />
If you want something other than basicHttpBinding for http requests, you can do this in the protocols section:
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="wsHttpBinding" bindingConfiguration="" />
The key in your situation is to you'll need to create the binding with larger values, and then either set it as the default or assign it to an endpoint (which you'll also need to define).
As I said, these are just simple examples to give you an idea, and there's a lot more detail in the article I linked.
IIS 7.0 on Windows 2008
WCF Web Service, .NET 4 from VS 2010
Web service is installed via publishing and I have full admin rights on the server. There are several complicated methods, but there is a simple one that returns the build version. If we can get this one working, I can fix them all - here is my interface:
namespace MyNameSpace
{
[ServiceContract]
public interface WebInterface
{
[OperationContract]
[WebGet]
string GetVersion();
Attempt to connect via HTTP:// and everything works fine!
Attempt to conenct via HTTPS:// I get a 404 file not found.
I can reach the generic "You have created a web service..." page, including full web service path and the C# generic sample code when browsing to the exact same URL's both on HTTP and HTTPS.
In C#, I have read that the certificate can cause trouble, and I have already implemented the delegate overload to approve our server certificate.
I suspect missing one or more entries in the Web.config file, but I don't have a clue where to start. I have tried Google searching and Stack Overflow searching, but I haven't found the correct combination of search terms to help with this particular issue.
Web Config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="HttpGetMetadata">
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="LinkService" behaviorConfiguration="HttpGetMetadata">
<endpoint address="" contract="WebInterface" binding="basicHttpBinding" />
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Help Please.
You're using the defaults for basicHttpBinding, and the default security mode for that binding is None. You need to define the binding and set the security mode to Transport in your config. Add a Bindings section to your ServiceModel section, like this:
<serviceModel>
<Bindings>
<basicHttpBinding name="secureBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</basicHttpBinding>
</Bindings>
</serviceModel>
Then you need to assign this binding to your endpoint via the bindingConfiguration attribute, like this:
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="secureBinding"
contract="WebInterface" />
You'll probably want to enable httpsGetEnabled as well:
<serviceMetadata httpGetEnabled="true"
httpsGetEnabled="true" />
See BasicBinding with Transport Security (which is what the sample code is based on).
You can also google with terms like "BasicHttpBinding WCF SSL" and stuff like that - lots of examples and information on the web, it's just a matter of using the right words :)
Also, I'm not 100% confident that the transportClientCredential setting is correct for your scenario (it might need to be Certificate), but I've done very little with SSL for WCF.
There may be other issues as well (like how IIS is set up on your machine), but the above is what's needed for the config.
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.
We're using UsernamePasswordValidator along with a certificate to secure access to our WCF services.
However, the custom authorization policies we're using are SERVICE behaviors, not endpoint behaviors, so they apply to all endpoints, including the MEX endpoint. We'd like to be able to go and grab the service references using visual studio without having to comment out the service behaviors every time, but since both the mex and the wshttp endpoint are secured, we get an error when doing "Add Service Reference.."
Is there any way around this?
Are you using the same binding on both? If so, try 2 seperate bindings - one for the mex endpoint and one for the wshttp:
So for the service - something like:
<wsHttpBinding><binding name="wsHttpBindingMessageUname">
<security mode="Message">
<message clientCredentialType="UserName" negotiateServiceCredential="true"
establishSecurityContext="false" />
</security></binding></wsHttpBinding>
and for the mex endpoint (no security):
<customBinding><binding name="customMex">
<textMessageEncoding>
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</textMessageEncoding>
<httpTransport transferMode="Buffered"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647"/></binding></customBinding>
Service endpoints will be something like:
<endpoint address="" behaviorConfiguration="Server.Services.DefaultEndpointBehavior" binding="wsHttpBinding" bindingConfiguration="wsHttpBindingMessageUname" name="DefaultHttp" contract="Server.Services.IMyService" listenUriMode="Explicit" />
<endpoint address="mex" binding="customBinding" contract="IMetadataExchange" name="" bindingConfiguration="customMex" listenUriMode="Explicit" />
With this setup, it's not applying the security for mex so you shouldn't get that message when trying to update service reference. Either that, or create another secure binding that uses different credentials, i.e. a client certificate on your machine.
The following MSDN post has a sample of this and more info can be found on this blog regarding secure mex endpoints.
I think from the question he also noted that he was using Service Behaviours, so the binding configuration wont make a difference, since the entire service uses the UserNamePassword Validator.
Two things come to mind here.
Remove the explicit mex binding and add under service behaviors
<serviceMetadata httpsGetEnabled="true" />
Or Keep the mex binding, and enable
<serviceMetadata httpGetEnabled="true" />
CustomUserNameValidator doesnt get executed when requesting Metadata,
so if httpsgetenabled isnt on, and you have a mex binding on http, you need
httpGetenabled on at least