I want to set the maxReceivedMessageSize in the App.config of the WCF Client.
If the maxReceivedMessageSize equals or is smaller then 4215 it works fine. Though when setting it to 4216 or any value above it, the default value of 65536 is taken.
My Client Code
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IConexaApiServic" maxReceivedMessageSize="4216" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://svsr02.conexa.local/HelloService/ConexaApiService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IConexaApiServic"
contract="ConexaApiService.IConexaApiService" name="BasicHttpBinding_IConexaApiService" />
</client>
</system.serviceModel>
</configuration>
And The relavant Server Code
<basicHttpBinding>
<binding name="BasicHttpEndpoint_MPSAPIServic" maxReceivedMessageSize="2000000">
<security mode="TransportWithMessageCredential" />
</binding>
<binding name="BasicHttpEndpoint_HelloService" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="2000000">
</binding>
</basicHttpBinding>
<service name="IIS_test123.HelloService">
<endpoint address="ConexaApi" binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpoint_HelloService" contract="IIS_test123.IHelloService"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/API/ConexaApiService" />
</baseAddresses>
</host>
</service>
</services>
Any idea how to fix this?
This can be explainned. If you look at your exceptions:
System.ServiceModel.CommunicationException is an exception thrown from client side. It has the maxReceivedMessageSize from the client side. Everything is fine.
FaultException: this exception is a SOAP fault that propagate the exceptions from the service to the client application. ( http://www.codeproject.com/Articles/799258/WCF-Exception-FaultException-FaultContract). So this exception is actually coming from the service side! The maxReceivedMessageSize is the default value, and does not correspond to the maxReceivedMessageSize in your server configuration.
The address you are connecting to in your client is the service address, not configured maxReceivedMessageSize, and not the endpoint address ConexaApi which is configure with maxReceivedMessageSize="2000000". That' s why you are getting the default 65536.
And 4215 must be the size of your message if you consider that the exception does not raise if you increase it.
Related
I have self hosting WCF service that contains it's own app.Config to expose endpoints required for the service contracts. If the service is started in the programs.cs main method it all works just fine and the metadata is exposed via the browser. However, I created a HostService class based on the ServiceBase class which in the same host library and is instantiated within the program.cs file. The HostService class starts the service and has a timer method to ping other client web services for information.
My question is, when I created the HostService : ServiceBase class and instantiate it from the main(), I have to put a duplicate app.Config file in the Service Library in order for the endpoints to properly exposed and return the metadata/wsdl. I don't want to maintain 2 duplicate app.config files if possible. Currently the host library and service library both require one. Is there a way to only have just one w/ the host that could be used for both? Sorry for the dumb question, but I'm new to WCF =)
Program.cs
static void Main(string[] args){
var service = new HostService();
service.StartHostService(args);
}
HostService.cs
public partial class HostService : ServiceBase
{
internal void StartHostService(string[] args)
{
this.OnStart(args);
Console.ReadLine();
this.OnStop();
}
....
}
Short answer is no. There must be two configs, one for the client that consumes the WCF and one for the server that exposes that communication methods with the WCF.
In order for your client to work, your config must be set with Client Configuration
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<client>
<endpoint
name="endpoint1"
address="http://localhost/ServiceModelSamples/service.svc"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IHello"
behaviorConfiguration="IHello_Behavior"
contract="IHello" >
<metadata>
<wsdlImporters>
<extension
type="Microsoft.ServiceModel.Samples.WsdlDocumentationImporter, WsdlDocumentation"/>
</wsdlImporters>
</metadata>
<identity>
<servicePrincipalName value="host/localhost" />
</identity>
</endpoint>
// Add another endpoint by adding another <endpoint> element.
<endpoint
name="endpoint2">
//Configure another endpoint here.
</endpoint>
</client>
//The bindings section references by the bindingConfiguration endpoint attribute.
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IHello"
bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard">
<readerQuotas maxDepth="32"/>
<reliableSession ordered="true"
enabled="false" />
<security mode="Message">
//Security settings go here.
</security>
</binding>
<binding name="Another Binding"
//Configure this binding here.
</binding>
</wsHttpBinding>
</bindings>
//The behavior section references by the behaviorConfiguration endpoint attribute.
<behaviors>
<endpointBehaviors>
<behavior name=" IHello_Behavior ">
<clientVia />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
notice the <client> tag specifying how the client must call the WCF.
and with Server Config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="myBindingConfiguration1" closeTimeout="00:01:00" />
<binding name="myBindingConfiguration2" closeTimeout="00:02:00" />
<binding closeTimeout="00:03:00" /> <!—- Default binding for basicHttpBinding -->
</basicHttpBinding>
</bindings>
<services>
<service name="MyNamespace.myServiceType">
<endpoint
address="myAddress" binding="basicHttpBinding"
bindingConfiguration="myBindingConfiguration1"
contract="MyContract" />
<endpoint
address="myAddress2" binding="basicHttpBinding"
bindingConfiguration="myBindingConfiguration2"
contract="MyContract" />
<endpoint
address="myAddress3" binding="basicHttpBinding"
contract="MyContract" />
</service>
</services>
</system.serviceModel>
</configuration>
Notice there is no <client> tag here.
Server's App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true"/>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="NewBehaviour">
<serviceMetadata httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="Binding">
<security mode="Transport">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="Server.InternalClass" behaviorConfiguration="NewBehaviour">
<endpoint address="IInternal" binding="wsHttpBinding" bindingConfiguration="Binding" contract="Common.IInternal">
<identity>
<dns value="MyMachine"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="https://MyMachine:8733/"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
Client
static ChannelFactory<IInternal> factory = new ChannelFactory<IInternal>(new WSHttpBinding(), new EndpointAddress("https://MyMachine:8733/IInternal"));
When i call the method factory.CreateChannel(), i get error
I configure certificate
You have to tell the client to use a secure transport channel so that it uses https instead of http. This is true because the binding settings at the client must match the ones at the service side.
You can do this via configuration in the app.config file of the client, or you can do it via code like this:
var ws_http_binding = new WSHttpBinding();
ws_http_binding.Security.Mode = SecurityMode.Transport;
ChannelFactory<IInternal> factory =
new ChannelFactory<IInternal>(
ws_http_binding,
new EndpointAddress("https://MyMachine:8733/IInternal"));
var channel = factory.CreateChannel();
I've a WCF library with some functions I use from Powershell and C# clients. Now I would like to use a couple of util functions directly from a browser but I'm not sure how to do.
First I added a webHttpBinding endpoint in the Web.config file, here is a slice
<services>
<service name="MI_lib.MainService">
<endpoint name="basic" address="" binding="basicHttpBinding" bindingConfiguration="MI_lib_http" contract="MI_lib.InterfaceMainService"></endpoint>
<endpoint name="web" address="web" binding="webHttpBinding" bindingConfiguration="MI_lib_web" contract="MI_lib.InterfaceMainService"></endpoint>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="MI_lib_http" />
</basicHttpBinding>
<webHttpBinding>
<binding name="MI_lib_web" crossDomainScriptAccessEnabled="true">
<security mode="None"></security>
</binding>
</webHttpBinding>
</bindings>
A simple function define for test purposes is this
[OperationContract]
[WebGet]
string GetData(int value);
Then if I connect to http://localhost/MI_lib/MI_lib.MainService.svc/web I get the following fault message
<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
<Code>
<Value>Sender</Value>
<Subcode>
<Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</Value>
</Subcode>
</Code>
<Reason>
<Text xml:lang="de-CH">The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).</Text>
</Reason>
</Fault>
Any hint on what to check or which other information to provide?
To define a web endpoint, you need, in addition to using the webHttpBinding, to add a web http behavior to your endpoint, as shown below:
<services>
<service name="MI_lib.MainService">
<endpoint name="basic" address="" binding="basicHttpBinding" bindingConfiguration="MI_lib_http" contract="MI_lib.InterfaceMainService"></endpoint>
<endpoint name="web"
address="web"
binding="webHttpBinding"
bindingConfiguration="MI_lib_web" contract="MI_lib.InterfaceMainService"
behaviorConfiguration="MyWeb">
</endpoint>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="MI_lib_http" />
</basicHttpBinding>
<webHttpBinding>
<binding name="MI_lib_web" crossDomainScriptAccessEnabled="true">
<security mode="None"></security>
</binding>
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="MyWeb">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
Also, the URL that you need to use also includes the method name, so you'll need to connect to
http://localhost/MI_lib/MI_lib.MainService.svc/web/GetData?value=123
I have a Wcf Service project. system.serviceModel tag in my web.config is :
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="RCISPNetTcpBinding" openTimeout="00:10:00" sendTimeout="00:10:00">
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign">
</transport>
<message clientCredentialType="Windows"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service behaviorConfiguration="RCISP.WcfServiceBehaviour" name="RCISP.WcfService.PersonWcfService">
<endpoint address="PersonServices" binding="netTcpBinding" bindingConfiguration="RCISPNetTcpBinding"
contract="RCISP.Common.ServiceContract.IPersonService" >
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:40003/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="RCISP.WcfServiceBehaviour">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceAuthorization principalPermissionMode="UseWindowsGroups" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
I have a runtime error when I want create self-hosting for service.
public class ServiceFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
if (!IsInitialised) InitialiseService();
return base.CreateServiceHost(serviceType, baseAddresses);
}
}
Message of Exception is :
Could not find a base address that matches scheme net.tcp for the endpoint with binding NetTcpBinding. Registered base address schemes are [http].
Why?
You said you were self hosting the service (within your own process) but based on the code above I think you're trying to host it inside of a web application. If so Visual Studio's web server can not host a net.tcp end point. You'll need to set the project up to run under IIS. Please follow the instructions here .
If you are truly self hosting than you can leave the configuration exactly how you have it and spin up the service using the following code:
var host = new ServiceHost(typeof(Service1));
host.Open();
You need to add a protocol mapping to your configuration file to tell it what the "net.tcp" protocol is. Right after your <bindings> section add this:
<protocolMapping>
<add scheme="net.tcp" binding="netTcpbinding"/>
</protocolMapping>
I am using VSTS 2008 + C# + .Net 3.0. I am using self-hosted WCF. When executing the following statement (host.Open()), there is the following binding not found error. I have posted my whole app.config file, any ideas what is wrong?
ServiceHost host = new ServiceHost(typeof(MyWCFService));
host.Open();
Error message,
The value of the property 'algorithmSuite' cannot be parsed. The error is: The value 'Aes128' is not a valid instance of type 'System.ServiceModel.Security.SecurityAlgorithmSuite'.
EDIT1: I have changed the algorithm suit option value to Default, but met with a new error when executing Open(), error message is, any ideas what is wrong,
Binding validation failed because the WSHttpBinding does not support reliable sessions over transport security (HTTPS). The channel factory or service host could not be opened. Use message security for secure reliable messaging over HTTP.
Full app.config,
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="MyBinding"
closeTimeout="00:00:10"
openTimeout="00:00:20"
receiveTimeout="00:00:30"
sendTimeout="00:00:40"
bypassProxyOnLocal="false"
transactionFlow="false"
hostNameComparisonMode="WeakWildcard"
maxReceivedMessageSize="100000000"
messageEncoding="Mtom"
proxyAddress="http://foo/bar"
textEncoding="utf-16"
useDefaultWebProxy="false">
<reliableSession
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Digest"
proxyCredentialType="None"
realm="someRealm" />
<message clientCredentialType="Windows"
negotiateServiceCredential="false"
algorithmSuite="Default"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="MyWCFService"
behaviorConfiguration="mexServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="https://localhost:9090/MyService"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="MyBinding" contract="IMyService"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="mexServiceBehavior">
<serviceMetadata httpsGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
thanks in advance,
George
You need to update your service behavior, too, if you change the MEX endpoint from http to https - you need to enable the httpsGetEnabled setting (not the httpGetEnabled):
<behaviors>
<serviceBehaviors>
<behavior name="mexServiceBehavior">
<serviceMetadata httpsGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
UPDATE:
George, check out this MSDN link - there is no "Aes128" algorithm - you must pick one of the existing ones.
UPDATE 2:
Can you try this config - reduce to the max! :-)
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="MyBinding"
maxReceivedMessageSize="100000000"
messageEncoding="Mtom"
proxyAddress="http://foo/bar"
textEncoding="utf-16"
useDefaultWebProxy="false">
<reliableSession enabled="false" />
<security mode="None" />
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="MyWCFService"
behaviorConfiguration="mexServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="https://localhost:9090/MyService"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="MyBinding" contract="IMyService"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="mexServiceBehavior">
<serviceMetadata httpsGetEnabled="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Can you start up your service,and can you add service reference from Visual Studio?
UPDATE 3:
George, I'd recommend you have a look at those security-related links and get some feel for what you really need and want - and how to achieve it.
WCF Security Guide
WCF Security Fundamentals
Fundamentals of WCF Security
MSDN Webcast Series "WCF Top To Bottom"
esp. Episode 10 - Security Fundamentals
Marc
The error message is correct, you don't get reliable messages over WSHttp, you need to use a custom binding and protocol.