Whenever I connect my client to send data to my WCF Azure service, I get this error:
"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."
I've read everywhere about setting this MaxReceivedMessageSize property on both the client and server config files. I have done this.
However, whenever I update the service reference in the client, it pulls the settings back to the default of 65536. (found via investigating the .svcinfo file)
This leads me to conclude the issue must be on the service side.
I've placed this in my web.config file:
<bindings>
<basicHttpBinding>
<!--The basicHttpBinding is used for clients which use the generated code to transmit data; the following settings make it possible to send larger amounts to the service-->
<binding maxReceivedMessageSize="10000000" receiveTimeout="01:00:00">
<readerQuotas maxStringContentLength="10000000" />
</binding>
</basicHttpBinding>
</bindings>
Now, many posts talk about naming the binding and setting it in the service endpoints on the server side as well. Something like this:
<services>
<service name="YourNamespace.YourServiceClass">
<endpoint name="endpoint1"
address="http://server:8888/YourService.svc"
binding="basicHttpBinding"
bindingConfiguration="lageMessageTransfer"
contract="IYourServiceContract" />
</service>
</services>
However, I don't have these service endpoints and my service works great for small sizes.
Where else would this need to be set?
EDIT:
More information, Tim seems to be on the right track with the default endpoints. I am using a default endpoint. It seems that you cannot just explicitly define a service for that default endpoint. or if you can, I must be doing it incorrectly.
However, it seems that you can modify the binding on a default endpoint as stated by Richard. This is done by simply not specifying a name for the binding. I have tried setting the values on my service to much lower values to see if something else was lowering them, but they are completely ignored. Its as if the default endpoint is simply ignoring the binding that I have created.
For my entire config file:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="logging.e2e" />
</listeners>
</source>
</sources>
</system.diagnostics>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding maxReceivedMessageSize="100" maxBufferSize="100" receiveTimeout="00:11:00">
<readerQuotas maxStringContentLength="100" />
</binding>
</basicHttpBinding>
</bindings>
<protocolMapping>
<add scheme="http" binding="basicHttpBinding" />
</protocolMapping>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="false" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<connectionStrings><EDITEDOUT></connectionStrings>
</configuration>
Thoughts on why the new binding settings are not being picked up?
The attribute name maxReceivedMessageSize is very explicit - it all depends on who is receiving the message - if you are sending a large amount of data then it is the service, if you are getting a large amount of data back from the service then it is the client. The service and client do not need the same value for this setting (unlike many other binding settings)
Setting an unnamed binding section should work in general as, of .NET 4, it configures the binding for anyone who doesn't explicitly specify a configuration using bindingConfiguration. However, in your example above you need to set the maxBufferSize in addition to the maxReceivedMessageSize as you are buffering rather than streaming the message. The maxBufferSize and maxReceivedMessageSize must be the same
You don't have the section in the Web.config on your service side? If you're using WCF 4.0 is it possible you're using a default endpoint?
I don't know if you can specify a binding for a default endpoint, but you might want to try specifying an endpoint via the section of the Web.config and setting bindingConfiguration to the binding specified in your section.
Related
Over the past few weeks I have developed a 64-bit WinForms application that needs to communicate with a 32-bit DLL (job specs require it).
After doing some reading around the internet and finding out that there is not going to be any fun way of doing this, I decided to go with hosting a WCF Service Application within my WinForms application for communicating to the 32-bit DLL... or so I thought I was doing.
During development (while running within Visual Studio) it has been working really well, but of course, now that I need to deploy, I am running into problems. I am having trouble getting a strong enough understanding of WCF Services to know if I am going about this in a terrible way or if I am just missing some minute detail.
I created the project as Admin. After development was finished I tried to run the WinForm executable (both debug and release), WindowsFormsApplication1.exe. The application started up, but after I tried to complete a task involving the use of the WCF service, an exception was thrown:
This has led me to believe that Visual Studio was doing the hosting of the service during development instead of the WinForm application, or my configs and/or directory structures are incorrect.
[UPDATED] WCF Service Web.config:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.2" />
<httpRuntime targetFramework="4.5.2" maxRequestLength="2147483647"/>
</system.web>
<system.net>
<defaultProxy>
<proxy usesystemdefault="False"/>
</defaultProxy>
</system.net>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing"
propagateActivity="true" >
<listeners>
<add name="xml"/>
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="xml"/>
</listeners>
</source>
<source name="myUserTraceSource"
switchValue="Information, ActivityTracing">
<listeners>
<add name="xml"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="C:\logs\Traces.svclog" />
</sharedListeners>
</system.diagnostics>
<system.serviceModel>
<diagnostics wmiProviderEnabled="true">
<messageLogging
logEntireMessage="true"
logMalformedMessages="true"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="true"
maxMessagesToLog="3000"
/>
</diagnostics>
<behaviors>
<serviceBehaviors>
<behavior name="metadadiscovery>
<!-- 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="ServiceReference1.Service1" behaviorConfiguration="metadadiscovery">
<endpoint address="" binding="basicHttpBinding" contract="ServiceReference1.IService1"></endpoint>
</service>
</services>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</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="false"/>
</system.webServer>
</configuration>
WinForm App.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService2" />
<binding name="BasicHttpBinding_IService3" />
<binding name="BasicHttpBinding_IService1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:45053/Service2.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService2" contract="ServiceReference2.IService2"
name="BasicHttpBinding_IService2" />
<endpoint address="http://localhost:46351/Service3.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService3" contract="ServiceReference3.IService3"
name="BasicHttpBinding_IService3" />
<endpoint address="http://localhost:44848/Service1.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
name="BasicHttpBinding_IService1" />
</client>
</system.serviceModel>
<appSettings>
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
<system.web>
<membership defaultProvider="ClientAuthenticationMembershipProvider">
<providers>
<add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
</providers>
</membership>
<roleManager defaultProvider="ClientRoleProvider" enabled="true">
<providers>
<add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
</providers>
</roleManager>
</system.web>
</configuration>
Directory Where EXE resides:
The directory containing the WCF Service resides within the directory WcfService1 from the image above.
I have mostly been using the following method of instantiating the service:
ServiceReference1.Service1Client = new ServiceReference1.SErvice1Client();
Once I tried to switch to using a service host (below), but when I used that method, the service would timeout whenever it tried to communicate to the DLL.
Uri address = new Uri("http://localhost:44848/Service1.svc");
ServiceHost host = new ServiceHost(typeof(ServiceReference1.Service1Client), address);
host.Open();
And then I closed the host later. At this point, I am willing to try anything to get this working.
[EDIT] Below is the code of my WindowsFormsApplication1.exe.config file. All three contracts are giving the warning that they're "invalid according to its datatype 'clientContractType'". I think this could be the source of my problems, but I do not know why it is showing this warning:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService2" />
<binding name="BasicHttpBinding_IService3" />
<binding name="BasicHttpBinding_IService1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:45053/Service2.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService2" contract="ServiceReference2.IService2" name="BasicHttpBinding_IService2" />
<endpoint address="http://localhost:46351/Service3.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService3" contract="ServiceReference3.IService3" name="BasicHttpBinding_IService3" />
<endpoint address="http://localhost:44848/Service1.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1" name="BasicHttpBinding_IService1" />
</client>
</system.serviceModel>
</configuration>
Thank you for any help and guidance you can provide.
There is no endpoint configured for your service.
<behaviors>
<serviceBehaviors>
<behavior name="metadadiscovery">
<!-- 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="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<service name="ServiceReference2.Yourimplementingservice" behaviorConfiguration="metadadiscovery">
<endpoint address="" binding="basicHttpBinding" contract="ServiceReference2.IService2">
</endpoint>
Above I have configured for Service2 ,similarly you have to configure for Service1 and Service3.
After sufficient struggling I decided to get rid of the WCF service that visual studio generates for you when you create it as a new project. I instead followed this tutorial verbatim:
Hosting Service In App
Doing this came with huge advantages:
No configuration file was necessary
Running it this way must've gotten rid of a large amount of overhead because the communication to the DLL (what I am using the service for) used to take several seconds to do large amounts of calls to the DLL, but now is able to handle 10k+ calls in the blink of an eye.
No service reference is necessary. I just needed the file for my main function, the file containing the service function implementations and the file containing the interface for the implementation.
So far, this has been the easiest and most robust way I have found for using a 32 bit DLL in a 64 bit application. Let me know if I can give any guidance for anyone else who may be struggling with this problem. I know this is not a fun thing to deal with if you've never done anything like it before.
We have a web service with both WSE 3.0 endpoints and the newer WCF endpoints on .NET Framework 4.5.
WCF is using basicHttpBinding.
The problem is that the new WCF bindings appear to be significantly slower (~3x). Does it use the same mechanism under the hood?
I've read a lot about enabling WCF tracing. But when I enable that on production I get way to much information and don't really know how read e.g. the timeline in Microsoft Trace Viewer.
I would appreciate any help
Tips for finding causes of the performance difference
Idea from a theoretical standpoint, e.g. are there any major differences under the hood in how WCF processes a request?
Any tools that can help to profile WCF server
Notes:
The issue exists in production; on the test servers everything goes
fine. At first we suspected that the load balancer might be a factor,
but disabling the load balancer does not change the performance at all
The slowness could be due our application/domain layer of course.
Maybe some thread/connection pool is blocking and messages are getting
queued because of that.
In this case does anyone have an idea why the behaviour is so
different from WSE (which runs on the same application pool)? Did any
queue sizes/concurrent processing default configurations change
dramatically between WSE3.0 and WCF?
Is there a way to find out when this is happening? E.g. some perfmon counters to watch? In perfmon I just get lost choosing between the huge amount of performance counters available
Update
Here's an anonymized version of our service Web.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="microsoft.web.services2" type="Microsoft.Web.Services2.Configuration.WebServicesConfiguration, Microsoft.Web.Services2, Version=2.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<system.web>
<httpRuntime executionTimeout="900" maxRequestLength="10240" />
<webServices>
<!--<wsdlHelpGenerator href="CustomizedWebServicePage.aspx" />-->
<protocols>
<add name="HttpGet" />
<add name="HttpPost" />
</protocols>
<soapExtensionTypes>
<add type="Microsoft.Web.Services2.WebServicesExtension, Microsoft.Web.Services2, Version=2.0.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" priority="1" group="0" />
</soapExtensionTypes>
</webServices>
<compilation defaultLanguage="cs" debug="true" targetFramework="4.5" />
<customErrors mode="RemoteOnly" />
<!-- dev only - application pool identity is configured on real environment -->
<identity impersonate="true" userName="ServiceIdentity" password="********" />
<authentication mode="Windows" />
<authorization>
<allow users="*" />
<!-- Allow all users -->
</authorization>
<trace enabled="false" requestLimit="10" pageOutput="false" traceMode="SortByTime" localOnly="true" />
<sessionState mode="InProc" cookieless="false" timeout="20" sqlConnectionString="data source=127.0.0.1;user id=someuserid;password=********;port=42424" />
<globalization requestEncoding="utf-8" responseEncoding="utf-8" />
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
</system.web>
<microsoft.web.services2>
<diagnostics>
<detailedErrors enabled="true" />
</diagnostics>
<policy>
<cache name="policyCache.xml" />
</policy>
<security>
<timeToleranceInSeconds>43200</timeToleranceInSeconds>
<defaultTtlInSeconds>43200</defaultTtlInSeconds>
<x509 storeLocation="LocalMachine" verifyTrust="false" />
<securityTokenManager type="OurProduct.Business.Authentication.CustomUsernameTokenManager, OurProduct.Business, Version=5.0.2.11517, Culture=neutral" qname="wsse:UsernameToken" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" />
</security>
<messaging>
<maxRequestLength>10240</maxRequestLength>
</messaging>
</microsoft.web.services2>
<startup>
<supportedRuntime version="v2.0.50727" />
</startup>
<system.serviceModel>
<diagnostics wmiProviderEnabled="true">
<messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true" />
</diagnostics>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<services>
<service behaviorConfiguration="OurServiceBehavior" name="OurProduct.Service.OurService">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IXXXOurService" bindingNamespace="http://localhost/XXXOurService" contract="OurProduct.ServiceContracts.XXXOurService.IXXXOurService" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="OurServiceBehavior">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="OurProduct.Service.Validation.CustomUserNamePasswordValidator, OurProduct.Service" />
</serviceCredentials>
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IXXXOurService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:15:00" sendTimeout="00:15:00" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288000" maxBufferSize="524288000" transferMode="Buffered" maxReceivedMessageSize="524288000" messageEncoding="Mtom" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="524288000" maxStringContentLength="524288000" maxArrayLength="524288000" maxBytesPerRead="524288000" maxNameTableCharCount="524288000" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
<runtime>
<gcServer enabled="true" />
<gcConcurrent enabled="true" />
</runtime>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="10485761" /> <!-- 10 megabytes -->
</requestFiltering>
</security>
</system.webServer>
</configuration>
Your WCF service configuration file does not appear to have throttling values explicitly set. You may want to use performance monitor to track the WCF resources and/or adjust the default values to make sure you are not hitting the default throttle limit.
Service throttling (serviceThrottling) allows you to even out the load on your backend WCF servers and to enforce resource allocation. serviceThrottling behavior for backend WCF services is configured by modifying the values for the maxConcurrentCalls, maxConcurrentSessions, and maxConcurrentInstances parameters in the config file for the WCF service.
<serviceThrottling
maxConcurrentCalls="200"
maxConcurrentSessions="200"
maxConcurrentInstances="200" />
https://msdn.microsoft.com/en-us/library/ee377061%28v=bts.70%29.aspx
Using WCF diagnostics is great, but as far as I know you won't be able to get similar diagnostics from the Web Service so you won't have anything to compare against. However the diagnostics you are preparing in your answer will give you an indication of relative time spent in each phase of the service call.
I'll propose an alterative which should be very simple because you're using http / text in both cases. Just catch both of the responses using Fiddler or your favorite proxy tool and compare. And critically - make sure that you look at the http header, not just the body. Fiddler will tell you the round trip time and the size of the response, which should be enough.
What could this be? The obvious things:
I've experienced huge performance overhead (yes, around 3x) when using Windows Authentication with WCF. I've seen the message size blow out when using Windows Authentication due to a large encrypted blob in the header (from memory). This costs a lot of time in transmission alone.
Also on security, is the WCF request being encrypted? If you use message security then it will be packed on the server side and unpacked on the client side. This is also not free.
Multiple service instances. You should have your service set for multiple instances, which means that each operation will create its own service instance. This is the default behavior. Configured as an attribute on the service class itself, like [System.ServiceModel.ServiceBehavior(ConcurrencyMode = System.ServiceModel.ConcurrencyMode.Multiple)]
You are correct in that there are many performance counters for WCF. They are grouped by service, endpoint and operation. You probably want the service counters, as they have more information. Check the ServiceModelService 4.0 category, and look at
Calls (obviously)
Calls Per Second
Instances
Instances Created Per Second
I would suggest to debug this in the following way:
temporarily remove all authentication and security logic from both services and see if the problem remains
temporarily disable any business logic and possibly simplify the schema to a single variable
when you say performance is slower, do you mean a single user performance or a load test? when you check a single user do you make sure the server is warm?
if you time the execution duration of your logic (e.g. from start to end of the your server method implementation) - is it the same?
remember to cancel any logging / tracing while benchmarking
you can try to revert wcf to use XmlSerializer instead of DataContract
Sorry for answering in answer,I dont have enough reputation for comments.
Which specific informations (traces) you would like to see? If you have difficulties setting up tracing, I would recommend you using tool named SvcConfigEditor.exe. In it, you can open App.Config file of your WCF service and under "Diagnostics", you can enable tracing. After that, you can select whether you want to trace particular information - so called "Trace level" (more infromation about specific levels - Configuring tracing ). See screenshot of the tool:
After you trace required information, you can open the log in Microsoft Trace Viewer - in it, you can view time duration of each acitvity: For example consider this one (sorry - some labels are in Czech language):
Sorry, picture was unreadable, here is link to bigger one : Trace viewer
On the left, you can select particular activity - if you stretch the panel, you can even see start and end time. Also, you see the total duration of that activity. After you select it, in the top-left panel you can see all the calls, that belong to that activity and you can also see, which call took the most time to resolve (In "Time" column).
I try to understand how authentication in WCF works. There is a self-hosting service with https endpoint which is bound to one of my certificates. Everything works fine when
security mode="None"
then it works fine even on different machines. Same situation with
mode="Transport" and <transport clientCredentialType="None"/>
. When I try to add validation by UserName it works fine but only on localhost, when hosted on different machines I receive an error:
"An unsecured or incorrectly secured fault was received from other
party..."
Why doesn't it work with UserName password validation?
EDIT2: I Found that following exception is thrown on the server and catched(but only while on different machines) :"The security timestamp is invalid because its creation time ('2014-11-29T01:30:48.824Z') is in the future. Current time is '2014-11-28T14:51:52.704Z' and allowed clock skew is '00:05:00'.". I don't know where was this creation time taken, but surely not from another machine. What happens?
Second question is about certificates. When hosting https and bind address to certificate, should this certificate be installed on client machine as trusted? (I bind it with netsh)
Without following code I cannot connect to my wcf service:
System.Net.ServicePointManager.ServerCertificateValidationCallback =
((sender, certificate, chain, sslPolicyErrors) => true);
Is it certificate validation on client side? It checks if it exists and if it is issued by trusted issuer?
EDIT:
Additional question:
When I try to enter service secured endpoint with browser, it says this connection is not secure, not trusted source etc. On my service machine I have bound certificate to https and that certificate is MyCertificate which is issued by "CertificateIssuer". Now I installed into Service and Client machine that issuer certificate - I mean "CertificateIssuer" into Trusted Root Certification Authorities" and still I am not trusted event when I enter from the same machine. How should I configure it to be trusted?
Server config:
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true"/>
</appSettings>
<system.web>
<compilation debug="true"/>
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="SdrConfigExample.e2e"/>
</listeners>
</source>
</sources>
</system.diagnostics>
<system.serviceModel>
<services>
<service name="WcfService1.TestService" behaviorConfiguration="ServiceUsernameValidation">
<host>
<baseAddresses>
<add baseAddress="https://localhost:8734/Services/"/>
<add baseAddress="http://localhost:8735/Wsdl/"/>
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address="Test" binding="basicHttpBinding" contract="WcfService1.ITestService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the values below to false before deployment -->
<serviceMetadata 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="False"/>
</behavior>
<behavior name="ServiceUsernameValidation">
<serviceMetadata httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WcfSecurity.PasswordValidator,WcfSecurity"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding>
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>
Client config:
<?xml version="1.0"?>
<configuration>
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="SdrConfigExample.e2e"/>
</listeners>
</source>
</sources>
</system.diagnostics>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_ITestService">
<security mode="TransportWithMessageCredential" >
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://175.28.233.153:8734/Services/Test" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_ITestService" contract="ServiceReference1.ITestService"
name="BasicHttpBinding_ITestService" />
</client>
</system.serviceModel>
</configuration>
Server code:
ServiceHost host = new ServiceHost(typeof(TestService));
var uri = host.Description.Endpoints[0].Address.Uri;
var cert = FindCertificate("CN=MyCertificate");
if (!ReserveAddressForHttps(uri.Host, uri.Port, cert, 5000))
{
throw new Exception("Failed to assign service certificate into local interface.");
}
host.Open();
host.Description.Endpoints.ToList().ForEach(x => Console.WriteLine(x.Address));
Console.WriteLine();
Console.WriteLine("Service started...");
Console.ReadLine();
host.Close();
Client code:
TestServiceClient client = new TestServiceClient();
client.ClientCredentials.UserName.UserName = "hej";//this is valid
client.ClientCredentials.UserName.Password = "hej";
System.Net.ServicePointManager.ServerCertificateValidationCallback =
((sender, certificate, chain, sslPolicyErrors) => true);
try
{
var result = client.GetData(123);
Console.WriteLine(result);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
Console.ReadLine();
The purpose of the Security Timestamp is to guard against "Replay Attacks"
In your case, the creation date (set on the client) is nearly 12 hours after the date on the server. The most obvious explanation is that one of the clocks is set incorrectly.
Replay attack detection can be disabled, which isn't a security risk as requests have to be signed anyway to benefit from it.
Regarding the certificates, the procedure for installtion is documented on TechNet - note you can view whether the certificate has been installed correctly:
If you want to verify the Certificate has been installed you can load
the certificates snap in and you should see it under Certificates
–Current User-Trusted Root Certification Authorities-Certificates.
Once your browser trusts the certificate, your WCF client will too.
I am having a problem adding a custom WCF service reference to my WPF application. I have been working on this service and application for nearly 6 months now and have never run into this issue until today. Whenever I try and add the WCF service via "Add Service Reference," all of my methods that return List are trying to return T[] instead. When I configure the service reference and change the collection type to "System.Collection.Generics.List", It shows in the status bar that it is updating the reference code, but the methods in the WPF application are throwing errors stating that it can't implicitly convert from List to Array. It seemed to have happened after I pushed an update to the server, but the only thing that was changed was the way one of my objects is initialized. I have tried the following so far;
Cleaned the project
Cleaned the solution
Rebuild the solution
Manually deleted the obj/bin/Service Reference folders
Removed and re-published the wcf service
Restarted the server
Im at a complete loss and have no idea what to do at this point. Any help is greatly appreciated!
Update
I created a separate console project, and it hooks into the WCF service correctly once configured to return lists. Looks to be specifically an issue with the WPF project.
Update 2
I noticed the following errors showing up briefly when I try to build. They disappear after a while, but I don't know if this has anything to do with the issue. They are both in the App.config file.
The 'bindingConfiguration' attribute is invalid - The value 'BasicHttpBinding_ICustomService' is invalid according to its datatype 'serviceBindingConfigurationType' - The Enumeration constraint failed.
The 'contract' attribute is invalid - The value 'CustomServerSvc.ICustomServer' is invalid according to its datatype 'clientContractType' - The Enumeration constraint failed.
Update 3
Interestingly, this only seems to happen on the client side randomly after a build.
Adding in my web.config per request.
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="UnifyServer.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<connectionStrings>
<add name="DebugUnifyCS"
connectionString="connectionString"
providerName="System.Data.SqlClient" />
<add name="UnifyCS"
connectionString="connectionString"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5"/>
</system.web>
<system.serviceModel>
<client />
<bindings>
<basicHttpBinding>
<binding name="myBasicBinding" maxBufferPoolSize="524288" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647" receiveTimeout="00:30:00" sendTimeout="00:30:00">
<readerQuotas maxDepth="128" maxStringContentLength="2147483647"
maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
</basicHttpBinding>
</bindings>
<!--<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IUnifyServer" >
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>-->
<services>
<service name="UnifyServer.UnifyServer">
<endpoint address="UnifyServer" binding="basicHttpBinding" bindingConfiguration="myBasicBinding" contract="UnifyServer.IUnifyServer"></endpoint>
<host>
<baseAddresses>
<add baseAddress="http://unifysrv2012:19081/"/>
</baseAddresses>
</host>
</service>
<service name="UnifyServer.ServiceEndpoint">
<endpoint address="ServiceEndpoint" binding="basicHttpBinding" bindingConfiguration="myBasicBinding" contract="UnifyServer.IServiceEndpoint"></endpoint>
<host>
<baseAddresses>
<add baseAddress="http://unifysrv2012:19081/"/>
</baseAddresses>
</host>
</service>
</services>
<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" />
</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>
<applicationSettings>
<UnifyServer.Properties.Settings>
<setting name="UnifyServer_some_service" serializeAs="String">
<value>https://some.url.com/some_service.asmx</value>
</setting>
</UnifyServer.Properties.Settings>
</applicationSettings>
</configuration>
This happens often so when you are adding the reference to the WCF service check this:
In the "Add service reference" screen press the "Advanced..." button (at the bottom).
In the middle part of the "Service reference settings" screen that you just opened you'll see 2 combos where you specify the collection type, select the right ones and click ok.
I doubt any service reference is updated since you are getting error while updating service reference.
Try start by these steps, each step is independent to other & might be cause of issue:
Make sure [ServiceContract] is declared for the interface of your services, because this produces the exact error.
If you have re-factored code or changed any file/namespace. make sure its applied everywhere.
Use fully qualified service name in web.config with Namespace;
Make sure System.ServiceModel & System.Runtime.Serialization reference is not missing.
Delete .SUO (solution Users Option file) file after closing VS. This will reset the cache for XMLEditor component in VS.
Update
For error The 'bindingConfiguration' attribute is invalid - The value 'BasicHttpBinding_ICustomService' is invalid according to its datatype 'serviceBindingConfigurationType' - The Enumeration constraint failed.
Make sure all service interface/contract have [ServiceContract] attribute, methods have [Operation Contract].
Also make sure all DataContract Attributes have [DataMember] Or enum have [EnumMember] attribute.
Update 2
One case I have faced was some attribute wasn't able to serialize. e.g. I was returning DataSet that can't be serialized to binary by default by wcf, that cause the error.
In worst case, you have to separate Data contracts & reuse them & have to generate proxy manually using SVCUtil. I know it sounds crazy. But sometimes when all things doesn't work it seems to be working.
Let me know it works or not.
When I run WCF Test Client I get an error :
Error: Cannot obtain Metadata from
localhost:52875/ControllersInfo.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.
Metadata
contains a reference that cannot be resolved:
localhost:52875/ControllersInfo.svc'. There was no
endpoint listening at localhost:52875/ControllersInfo.svc that
could accept the message. This is often caused by an incorrect
address or SOAP action. See InnerException, if present, for more
details.
Here is my web.config file
<configuration>
<system.web>
<compilation debug="true" targetFramework="4.0">
<assemblies>
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</assemblies>
</compilation>
</system.web>
<system.serviceModel>
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint helpEnabled="true" automaticFormatSelectionEnabled="true" />
</webHttpEndpoint>
</standardEndpoints>
<services>
<service name="dev_FineReceiptsService.ControllersInfo">
<endpoint kind="webHttpEndpoint" contract="dev_FineReceiptsService.IControllersInfo" />
</service>
</services>
</system.serviceModel>
<connectionStrings>
<add name="FineReceiptsTestEntities" connectionString="metadata=res://*/FineTest.csdl|res://*/FineTest.ssdl|res://*/FineTest.msl;provider=System.Data.SqlClient;provider connection string="Data Source=msdev01;Initial Catalog=FineReceiptsTest;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
</connectionStrings>
</configuration>
Can anyone tell me what I have done wrong ?
I tried to find similar question but none of them helped me.
Your service is REST-based service (since you specified the webHttpBinding).
However, the WCF Test Client is a SOAP-based testing tool - you can test SOAP service with this - basicHttpBinding, wsHttpBinding etc.
But you cannot use the SOAP-based WCF Test Client to test your REST-based WCF service... that won't work. Use a regular web browser, potentially combined with Fiddler or something like that to test your REST services .
Metadata endpoints expose WSDL + XSDs which describes SOAP services. There is no support for exposing metadata for REST. Since your are using webHttpEndpoint, you can not use WCFTestClient. For testing a Rest Service, RestSharp or Browser can be used.
If you need to add metadata to SOAP service with simplfied configuration you need to add this behavior:
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>