WCF 4 and NetTcpBinding - c#

I am testing out the no configuration features of WCF 4.
I have built a simple service and deployed it to IIS. The service is deployed as a svc file
The client config is empty:
<configuration>
<system.serviceModel>
<bindings />
<client />
</system.serviceModel>
</configuration>
The config on the web server is:
<system.web>
<compilation debug="true" targetFramework="4.0" />
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
This code works fine:
BasicHttpBinding myBinding = new BasicHttpBinding();
EndpointAddress myEndpoint = new EndpointAddress("http://localhost/Service1.svc");
ChannelFactory<IService1> myChannelFactory = new ChannelFactory<IService1>(myBinding, myEndpoint);
IService1 wcfClient1 = myChannelFactory.CreateChannel();
int z = wcfClient1.Multiply(composite);
This code does not:
NetTcpBinding myBinding = new NetTcpBinding();
EndpointAddress myEndpoint = new EndpointAddress("net.tcp://localhost:808/Service1.svc");
ChannelFactory<IService1> myChannelFactory = new ChannelFactory<IService1>(myBinding, myEndpoint);
IService1 wcfClient1 = myChannelFactory.CreateChannel();
int z = wcfClient1.Multiply(composite);
The error that I get is:
Could not connect to
net.tcp://localhost/Service1.svc. The
connection attempt lasted for a time
span of 00:00:02.1041204. TCP error
code 10061: No connection could be
made because the target machine
actively refused it 127.0.0.1:808.
The net.tcp binding is set on the default web site.
I have a feeling that there is something simple that I am missing. Anyone have any ideas?

I get the feeling that your Net.Tcp Port Sharing Service is not enabled.

Found the problem. Although net.tcp looked like it was installed for the Default web site it needed to be activated using this command:
appcmd.exe set app "Default Web Site/" /enabledProtocols:http,net.tcp

Related

Entity Famework Data Service as a Windows Service how to change maxReceivedMessageSize

I'm trying to increase the maxReceivedMessageSize for my DataService. I've tried the solutions from these places:
https://malvinly.com/2011/05/09/wcf-data-services-and-maxreceivedmessagesize/
How do I setup config files for WCF Data Service (odata) with EF 6
and some other places I can't remember but I can't get it working. The DataService is not running for a Web Application but in a Windows Service. The app.config is currently looking like this:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" bindingConfiguration="Test"/>
</protocolMapping>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<bindings>
<basicHttpsBinding>
<binding name="Test" maxBufferSize="10485760" maxReceivedMessageSize="10485760">
<readerQuotas maxDepth="10485760" maxStringContentLength="10485760"
maxArrayLength="10485760" maxBytesPerRead="10485760" maxNameTableCharCount="10485760" />
</binding>
</basicHttpsBinding>
</bindings>
</system.serviceModel>
EDIT
I've updated the app.config content... Still can't figure out how this should be done.
EDIT
As recommended I've also set the readerQuotas without success
After a while we've found a solution...
Initially we took the DataServiceHost class to host our Service which does not support these options. After using WebServiceHost to host the service it worked:
WebServiceHost webServiceHost = new WebServiceHost(typeof(EfoDataService), new Uri[] { });
//Https binding
WebHttpBinding httpsbinding = new WebHttpBinding()
{
Security = { Mode = WebHttpSecurityMode.Transport },
MaxReceivedMessageSize = 2097152,
MaxBufferSize = 2097152,
MaxBufferPoolSize = 2097152,
TransferMode = TransferMode.Streamed
};
//adding https endPoint
webServiceHost.AddServiceEndpoint(typeof(IRequestHandler), httpsbinding, secureBaseAddress);
It's a bit strange though since DataServiceHost does derive from WebServiceHost.

WCF config file 413-request-entity-too-large

i have read multiple similar threads but still don't know what to do.
I've created simple WCF service which is getting some xml data (in strings)
Everything was working fine until project was running on windows 7.
Now, when i try to send data from client to WCF service i get exception
413-request-entity-too-large
i've tried to add these two parameters to my web.config on WCF service
maxBufferSize="2147483647"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
Can someone please look at my config and try to help me ?
WCF service code:
public class Service1 : IService1
{
public static Konfiguracja config;
public static DBqueries queries;
public void WczytajKonfiguracje()
{
config = new Konfiguracja();
queries = new DBqueries();
}
public bool? DodajInfoSprzet(int idKlienta, string haslo, int id_zgloszenia, string HardwareInfoXML, string SoftInfoXML)
{
...and some code
}
}
and here is my wcf web.config file:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="ProjektSerwisConnectionString" connectionString="Data Source=.\sql12;Initial Catalog=ProjektSerwis;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.6.1" />
<httpRuntime targetFramework="4.6.1"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647" />
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
(i've edited it by visual studio context menu on file web.config)
WCF service has been running by
namespace SelfService
{
class Program
{
static void Main(string[] args)
{
Uri baseAddress = new Uri("http://localhost:55555/WcfStart/");
ServiceHost selfHost = new ServiceHost(typeof(Service1), baseAddress);
try {
selfHost.AddServiceEndpoint(typeof(IService1), new WSHttpBinding(), "WmiService");
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);
selfHost.Open();
while(true)
{
Console.WriteLine("Usługa działa");
Console.WriteLine("Wpisz quit aby zakończyć działanie");
string command = string.Empty;
command=Console.ReadLine();
if (String.Equals(command.ToLower(), "quit".ToLower()))
break;
}
// Close the ServiceHostBase to shutdown the service.
selfHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}
}
}
}
and client has just references to web service and connect it by :
Service1Client scl = new Service1Client();
bool? ok = false;
try
{
ok = scl.DodajInfoSprzet(IdKlienta, haslo, IdZgloszenia, HardwareInfoXML, SoftInfoXml);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
i konw that i have pasted a lot of code, but i have no idea what to do with my web.config file
the data which is being sending is not big, it is less than 1 MB
Did you just put this configuration in the web.config?
Since you're hosting your WCF as a console application you have to make the configuration in the App.config of the hosting application.

Error calling WCF webservice through channelfactory - not permissioned

I am using a ChannelFactory to call into a WCF service (as the target service location will change depending on environment and I need the URL to be configurable). However I get the error:
The HTTP request is unauthorized with client authentication scheme
'Anonymous'. The authentication header received from the server was
'Negotiate,NTLM'.
My calling code
var myBinding = new BasicHttpBinding();
var myEndpoint = new EndpointAddress(webserviceAddress);
var myChannelFactory = new ChannelFactory<IObjectService>(myBinding, myEndpoint);
var serviceClient = myChannelFactory.CreateChannel();
My WCF service web.config system.servicemodel section
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding>
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" minFreeMemoryPercentageToActivateService="0" />
</system.serviceModel>
The service should be authenticated based on Windows Authentication. I would have thought by default the calling code above would use Windows Authentication to pass the account that the code is running as (a service account) but it seems to be sending anonymous
You must set the mode to transport with message credentials, as shown in the following code:
var myBinding = new BasicHttpBinding();
myBinding.Security.Mode = SecurityMode.TransportCredentialOnly;
As an alternative, you can set the mode in the constructor of the binding:
var myBinding = new BasicHttpBinding(SecurityMode.TransportCredentialOnly);
Also set the ClientCredential:
myBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

Castle Windsor WCF Facility HTTPS

I successfully integrated the Caste WCF Facility with my services. Now I try to configure an HTTPS communication based on BasicHttpBinding.
According the following blog post, this should not be a big deal: http://blog.adnanmasood.com/2008/07/16/https-with-basichttpbinding-note-to-self/
Here's my setup. On client-side, I configure the Windsor container using the following code:
BasicHttpBinding clientBinding = new BasicHttpBinding();
// These two lines are the only thing I changed here to allow HTTPS
clientBinding.Security.Mode = BasicHttpSecurityMode.Transport;
clientBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
// Everything else worked well with HTTP
clientBinding.MaxReceivedMessageSize = 163840;
clientBinding.MaxBufferSize = (int)clientBinding.MaxReceivedMessageSize;
container = new WindsorContainer();
container.AddFacility<WcfFacility>();
container.Register(
Component.For<IClientService>()
.AsWcfClient(new DefaultClientModel {
Endpoint = WcfEndpoint.BoundTo(clientBinding)
.At(configuration.Get(CFGKEY_SERVICE_CLIENT))
})
);
Besides that, I don't have any configuration on client-side. This worked well using HTTP communication.
The server side got the following configuration within Web.config:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
When I'm trying to connect through https://, I get the following exception:
System.ServiceModel.EndpointNotFoundException: There was no endpoint listening at https://myuri.com/Services/Client.svc that could accept the message.
Any ideas what's missing?
Thank you in advance.
Fixed it by myself, the above code is correct, the problem has been located inside my Windsor service installer on server-side. The following snippet for each service point will do the job.
As you can see, I've put the absolute service URI as well as transport mode (either http or https) into the app settings section of the Web.config file. Of course it would be nice to use the default WCF configuration model but this did not work.
.Register(
Component
.For<MyNamespace.ContractInterface>()
.ImplementedBy<MyNamespace.ImplementationClass>()
.Named("ServiceName").LifestylePerWcfOperation()
.AsWcfService(
new DefaultServiceModel().Hosted().AddEndpoints(
WcfEndpoint.BoundTo(new BasicHttpBinding {
Security = new BasicHttpSecurity {
Mode = (WebConfigurationManager.AppSettings["Service.WCFFacility.TransportMode"] == "http") ? BasicHttpSecurityMode.None : BasicHttpSecurityMode.Transport,
Transport = new HttpTransportSecurity {
ClientCredentialType = HttpClientCredentialType.None
}
}
}).At(WebConfigurationManager.AppSettings["Service.WCFFacility.Endpoint"])
)
)
);
The server configuration remains as shown above, except the app setting keys.
Hope this might help someone experiencing similar problems.

Where to put MaxReceivedMessageSize property in WCF service's web.config file?

I need to change my web.config file and add the MaxReceivedMessageSize property in
my web.config - but where?
The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.
<?xml version="1.0"?>
<configuration>
<system.web>
<compilation debug="false"><assemblies><add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /></assemblies></compilation>
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
You need to define a binding configuration for the binding you want to use and then you need to define your services (on the server-side) and clients (on the client side) to use that binding and binding configuration:
<system.serviceModel>
<bindings>
<!-- pick whichever binding you want .... -->
<basicHttpBinding>
<!-- binding configuration with a name -->
<binding name="ExtendedMaxSize"
maxBufferSize="999999" maxReceivedMessageSize="999999" />
</basicHttpBinding>
</bindings>
<services>
<service name="Yournamespace.YourServiceClass" behaviorConfiguration="...">
<!-- define endpoint with your binding and the name of the binding configuration
that you have defined just above -->
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="ExtendedMaxSize"
contract="Yournamespace.IYourServiceContract" />
</service>
</services>
To help those who may end up here like I did.
I cannot add to the comments above yet (Usually someone already has the answers long before I have the problem), so I have to add an answer.
I have an MVC 4 app, and I suspect the initial sample above is from the web.config of the actual WCF service project. One of the comments mentions they suspect it is an MVC 4 app and the default config settings.
But how do you fix the problem? From more research, it appears that the change actually needs to be made to the web.config for the CLIENT, in other words, the web config for the project with the REFERENCE to the WCF service. You will find it is much easier to make the change there. That version of the web.config will actually resemble what you are looking for.
That worked easily for me and fixed my issue.
No need, contrary to often claimed, to set on the server.
Contrary to what MSDN is saying, it is not enough to set the limit on the transport binding element. Need to set on binding itself too.
For example:
var targetBinding = new BasicHttpsBinding();
targetBinding.MaxReceivedMessageSize = MaxWcfMessageSize;
targetBinding.MaxBufferPoolSize = MaxWcfMessageSize;
targetBinding.MaxBufferSize = MaxWcfMessageSize;
var targetBindingElements = targetBinding.CreateBindingElements();
var httpsBindElement = targetBindingElements.Find<HttpsTransportBindingElement>();
httpsBindElement.MaxReceivedMessageSize = MaxWcfMessageSize;
httpsBindElement.MaxBufferPoolSize = MaxWcfMessageSize;
httpsBindElement.MaxBufferSize = MaxWcfMessageSize;
TextMessageEncodingBindingElement tmbebe = targetBindingElements.Find<TextMessageEncodingBindingElement>();
tmbebe.ReaderQuotas.MaxArrayLength = MaxWcfMessageSize;

Categories

Resources