I have a windows application which calls to a WCF service to build a specific URL.
The WCF function which gets called from windows application accepts location details in the form of an array.
I face a problem the when array size sent to WCF function is small (for eg. 10) then the service returns correct result.
But when the array size grows (for eg. >200) then service returns a 400 Bad request.
I am not sure if the array size or the array contents are causing this problem.
I have tried to change the server (service) side web.config to accept the max buffer size.
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IServiceContract" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" messageEncoding="Text"
textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<system.web>
<compilation debug="true" targetFramework="4.0" />
<httpRuntime executionTimeout="90" maxRequestLength="1048576" useFullyQualifiedRedirectUrl="false"
minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="100" />
</system.web>
Still I am facing the same issue.
In client side (here windows application) how can we set the configuration settings so that client will be able to send large data to server side?
You need to increase the Reader Quota in the server config file as well as client config file.
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
And maxReceivedMessageSize and bufferSize:
<httpTransport transferMode="Buffered"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647"/>
You might also need to add dataContractSerializer into your Service Behaviour.
<serviceBehaviors>
<behavior name="Your SB">
<serviceMetadata httpGetEnabled="True"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
<serviceDebug
includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
You need to make the changes on the Client side. Change both maxBufferSize and maxReceivedMessageSize. I faced a similar problem just yesterday and fixed it by resetting those values to a higher value.
Note: In fact i didn't make any changes on the service(server).
Related
I tried setting up a WCF service in a demo application that when I tested it within the application it worked fine when running it. I then created the same service and tried to apply it to a dojo application where I call the service from a xhrpost function and the following error occurs
Failed to load resource: the server responded with a status of 404
(Not Found) http://localhost:51541/Service1.svc/load_data
After opening it up in the browser http://localhost:56252/Service1.svc, I then tested it using wcftestclient.exe and all methods within there worked. Is there something I am missing here.
webconfig portion:
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://locaxxxxx:56252/Service1.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
name="BasicHttpBinding_IService1" />
</client>
EDIT:
I found it referencing another port as mentioned but after removing the other project I now got the following error:
Failed to load resource http://localhost:56252/Service1.svc/load_data
I am facing issue of poor performance when used WCF having NetTcpbinding with Load Balancer
We have win form application which consumes WCF (net.tcp protocol). In production we have web Farm having 3 servers with load balancer (F5). WCF hosted in IIS. We are testing with only 1 user
Now when we point WCF to specific server (using either server name or IP); application really perform well. However when we give the DNS name (so that request is pass through load balancer) there is a significant drop in performance. Network team is saying from there side everything is properly working. Please help
Following is the configuration that i have tin WCF web.config file.
<system.serviceModel>
<diagnostics performanceCounters="All" />
<services>
<service behaviorConfiguration="GetProxyEnabled" name="companyname.InvOps.ServiceLayer.PAServiceServer">
<host>
<baseAddresses>
<add baseAddress="net.tcp://USHOUIOWEB012VT/PAService"/>
<!--<add baseAddress="net.tcp://xxx.uat.companyname.net/PAService/"/>-->
</baseAddresses>
</host>
<endpoint address="netTcpAddress" behaviorConfiguration="NetTcpEndPointBehaviour" binding="netTcpBinding" bindingConfiguration="NetTcpBinding" contract="companyname.InvOps.ServiceLayer.IPAService" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="GetProxyEnabled">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceThrottling maxConcurrentCalls="200" maxConcurrentInstances="400" maxConcurrentSessions="200"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="NetTcpEndPointBehaviour">
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding"
closeTimeout="05:45:00"
openTimeout="05:45:00"
receiveTimeout="05:45:00"
sendTimeout="05:45:00"
transactionFlow="false"
transferMode="Buffered"
transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard"
listenBacklog="10"
maxBufferPoolSize="2147483647"
maxBufferSize="2147483647"
maxConnections="10"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<reliableSession ordered="true"
inactivityTimeout="05:45:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
Really appretiate any feedback or suggesttion. Also what is the recommended settings on F5 when used WCF with NetTcpBinding.
I got it working now. It was Load Balance configuration issue. We have changed the Virtual Server type from Standard to Performance (Layer 7). The performance is not improved to acceptable range.
my purpose is to ensure that - when someone clicks on "Add Service Reference" in his own Visual Studio, and he adds references to my WCF service - he receives not the default settings, but the settings of the service.
In particular, there is a property of the "binding" class that interests me: useDefaultWebProxy, I need it setted to "false".
I tried this, but with no results:
In the Web.config file of the service:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="NewBinding0" ... useDefaultWebProxy="false">
<readerQuotas ... />
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="NewBehavior0" name="pippo.pluto">
<endpoint address="" behaviorConfiguration="" binding="basicHttpBinding"
bindingConfiguration="NewBinding0" name="pluto" contract="pippo.ipluto" />
<host>
<timeouts ... />
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="NewBehavior0">
<serviceMetadata ... />
<serviceDebug ... />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Nothing to do: in the client's Web.config I always get...
<basicHttpBinding>
<binding name="pluto" ... useDefaultWebProxy="true">
<readerQuotas ... />
<security ...>
<transport ... />
<message ... />
</security>
</binding>
</basicHttpBinding>
It seems that the bindingConfiguration of the service is completely ignored, not only useDefaultWebProxy but also other properties - for example maxBufferSize - maintain the default values (65536)
How can I do?
Pileggi
I am trying to get the Windows User name of the client who is accessing the ASP.NET page that is being hosted on my Local IIS. I am callign a WCF service within the ASP.NET page which returns the windows username of the client. I came across so many posts regarding and most of them are suggesting that
OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name
HttpContext.Current.User.Identity.Name
HttpContext.Current.User.Identity.Name
should work. The problems I am facing is "1" is always returning Null. "2" and "3" are always returning my local user name and not the requesting user's name. Am I missing anything in the web.configs of both ASP.NET and WCF service.
IIS properties: Integrated Windows authentication Enabled.
Here is the code.
WCF
public string GetWindowsUser()
{
string temp = OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name;
string temp1 = HttpContext.Current.User.Identity.Name;
string temp2 = HttpContext.Current.User.Identity.Name;
return "Temp: "+temp+" \nTemp1: "+temp1+" \nTemp2: "+temp2;
}
WEB.Config
<system.web>
<compilation debug="false" targetFramework="4.0"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:4772/Services.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="WindowsAuthServices.IService1" name="BasicHttpBinding_IService1"/>
</client>
</system.serviceModel>
ASP.NET Page:
protected void Page_Load(object sender, EventArgs e)
{
WindowsAuthServices.Service1Client client = new WindowsAuthServices.Service1Client();
lblWelcome.Text = client.GetWindowsUser();
}
Web.Config
<system.web>
<compilation debug="true" targetFramework="4.0"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="UserName" algorithmSuite="Default"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:4772/Services.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService1" contract="WindowsAuthServices.IService1" name="BasicHttpBinding_IService1"/>
</client>
</system.serviceModel>
This is because your call is done on behalf of the identity under which the ASP.Net worker process runs and not under the identity of the user requesting the page (which is called impersonation).
From http://geekswithblogs.net/robz/archive/2007/10/03/wcf-impersonation---specifying-windows-authentication-credentials-on-the-service.aspx
1) The ASP.NET client web.config file needed to have impersonation set using the following markup (I put it under the authentication element as shown):
<authentication mode="Windows"/>
<identity impersonate="true"/>
2) The service behavior had to be configured to use Windows for permissions and to impersonate callers.
<serviceBehaviors>
<behavior name="XXX.XXXXXXXXXXXX">
<serviceMetadata httpGetEnabled="True"/>
<serviceAuthorization principalPermissionMode="UseWindowsGroups" impersonateCallerForAllOperations="true" />
</behavior>
</serviceBehaviors>
Our enterprise wants its site to open only those using company
devices(laptops). So they want the sharepoint site to use Windows
authentication and not prompting the username and password. If the
windows username matches with the one in the list of approved users it
should open or else redirect to different authentication page. getting
1st part done has been a problem.
So you just need your laptops to be connected to windows domain and use Integrated security and set correct security groups in Sharepoint.
What you describe is not security and it will never work.
Sounds like you need to implement/configure your website for identity delegation. If you need to configure WCF for delegation, check out this MSDN article.
I finally found the solution. When the other user are trying to access my local IIS using IP, my local IIS assumes that it is an internet request and not intranet request and since its windows authentication, it works only with intranet requests. To solve this I had to host my website on one of our domain servers. Since the domain server was already setup such that only users in that domain can access it, now it has the windows login info. And there ends my misery.
I am trying to decide on an architecture for a change in my web service. I need to make a WCF service. I want to make only one service and then host it either in the IIS or in a Windows service. Is this even possible, making this kind of reuse of a WCF Service? How would I go about doing this? The scenario is that some of our customers do not have access to start a Windows service but can install a WCF in the IIS.
Thank you in advance.
A WCF service is simply an assembly that abides by the WCF hosting interface and then provides a client interface that allows it to be accessed.
Hosting a WCF service occurs equally in IIS, Windows service, WinForm application, or a console application. It truly doesn't matter.
The client interface remains unchanged, although how the interface is exposed might change depending on hosting scenario. For example, you'll probably use one the http bindings in the IIS case, but might use TCP binding for Windows services. These bindings can be defined in the config file, so the code doesn't necessarily have to change to accommodate being hosted one way or the other.
In short, creating the WCF service should be independent of how it will eventually be hosted. For ease of maintenance on your part, though, I'd pick one or the other - Windows service or IIS.
you could have a windows service host the WCF and expose all end points on it..Http,TCP..
Windows service is better than IIS because IIS is a process in itself and then we place upon it a VD to host our website/WCF.As for the Windows Service,it will be one dedicated thread catering only to the WCF.I am sharing the app.config of windows service (details changed) to show how we have hosted WCF...hope it helps..
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Off" propagateActivity="true" >
<listeners>
<add name="SERVICE_MONITOR" type="System.Diagnostics.XmlWriterTraceListener"
initializeData="MyApp_MONITOR.svclog" />
</listeners>
</source>
<source name="MyApp_TRACE" switchValue="All" >
<listeners>
<add name="MyApp_TRACE_LISTENER" type="System.Diagnostics.XmlWriterTraceListener"
initializeData="MyApp_TRACE.svclog" />
</listeners>
</source>
</sources>
<trace autoflush="true" />
</system.diagnostics>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="OverAllServiceBehavior">
<serviceSecurityAudit
auditLogLocation="Application"
serviceAuthorizationAuditLevel="Failure"
messageAuthenticationAuditLevel="Failure"
suppressAuditFailure="true" />
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True" />
<serviceThrottling maxConcurrentCalls="10000" maxConcurrentSessions="10000"
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="MyAppHost.Authenticate, MyAppHost"/>
<serviceCertificate findValue="MyApp_MESSAGE" storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName" />
<clientCertificate>
<authentication
certificateValidationMode="PeerTrust"
trustedStoreLocation="LocalMachine" />
</clientCertificate>
</serviceCredentials>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="OverAllEndPointBehavior" />
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="ServiceBasicHttpEndPointBinding" closeTimeout="00:00:59"
openTimeout="00:00:59"
messageEncoding="Text"
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</basicHttpBinding>
<wsHttpBinding>
<binding name="ServiceWSHttpEndPointBinding" closeTimeout="00:00:59"
openTimeout="00:00:59"
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
<netTcpBinding>
<binding name="ServiceTCPEndPointBinding" maxBufferSize="2147483647"
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<transport
clientCredentialType="Certificate"
protectionLevel="EncryptAndSign" />
<message clientCredentialType="UserName" algorithmSuite="TripleDes"/>
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service behaviorConfiguration="OverAllServiceBehavior"
name="MiddleWare.ServiceClasses.ServiceClass">
<host>
<baseAddresses>
<add baseAddress="net.tcp://127.0.0.1:15010/ServiceTCPEndPointMEX"/>
<add baseAddress="http://127.0.0.1:15020/ServiceHttpEndPointMEX"/>
<add baseAddress="https://127.0.0.1:15030/ServiceWSHttpEndPointMEX"/>
</baseAddresses>
</host>
<endpoint address="net.tcp://127.0.0.1:15040/ServiceTCPEndPoint"
contract="MiddleWare.ServiceContracts.IServiceContract" />
<endpoint address="http://127.0.0.1:15050/ServiceBasicHttpEndPoint"
contract="MiddleWare.ServiceContracts.IServiceContract"/>
<endpoint address="https://127.0.0.1:15060/ServiceWSHttpEndPoint"
contract="MiddleWare.ServiceContracts.IServiceContract"/>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
</system.serviceModel>
<appSettings>
<add key="UserName" value="USER"/>
<add key="Password" value="PASSWORD"/>
</appSettings>
</configuration>