I called an WCF service and tried fetching data from database in windows 7.
I got this error.
Error in deserializing body of reply message for operation
'GetProductXml'. The maximum string content length quota (8192) has
been exceeded while reading XML data. This quota may be increased by
changing the MaxStringContentLength property on the
XmlDictionaryReaderQuotas object used when creating the XML reader.
Line 13, position 197.
I tried changing the MaxStringContentLength property to 2147483647 in web config of WCF service but i get the same above error....
You need to change it in the client.config file that was created when you added a service reference in your windows 7 application.
You can get around the error by adding the below settings in your WCF Service web.config and also on your client side web.config:
<basichttpBinding>
<binding>
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="64" maxNameTableCharCount="2147483647" />
</binding>
</basichttpBinding>
NOTE: Assuming you are using BasicHttpBinding. If using a different binding make sure to add the readerQuotas for that binding.
If you are hosting your WCF service via code and then you want to add reader quotas via code see below:
var binding = new BasicHttpBinding();
var myReaderQuotas = new XmlDictionaryReaderQuotas();
myReaderQuotas.MaxStringContentLength = 5242880;
binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, myReaderQuotas, null);
Related
I am getting the following 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 am using WebhttpBinding which uses REST service.
There is no configuration setting from client side.
I am using MVC3 application.
Need help in stream more than 65536 bytes.
Is there any way to edit the ServiceHostFactory behaviour so that somewhere I can set MaxReceivedMessageSize property to 2GB
thanks for your response.
Since I am using WebHttpBinding,I would like to know how to override the ServiceHostFactory .
Creating a custom class and overriding the OnOpening() method of WebServiceHost can resolve the problem or not?
MaxReceivedMessageSize is a property of the binding element; if you need to change it from the defaults you have two options:
Use a configuration file, and set it from within a binding element.
Create the bindings in code and set the property there.
To do this on the client side, without a configuration file, you'll need to bypass the normal service reference code and create the client channel yourself. You can see an example of how to do this on my blog post about using WCF without the auto-generated client proxy: Proxy-Free WCF. In essence, you do something like this in code:
var binding = new WebHttpBinding();
binding.MaxReceivedMessageSize = int.MaxValue;
var factory = new ChannelFactory<IServiceInterfaceChannel>(binding);
var client = factory.CreateChannel(new Endpoint(SERVICE_URL));
If you need to change the behavior on the service side, you can specify a binding by calling AddServiceEndpoint on the service host class, for example:
var host = new WebServiceHost();
var binding = new WebHttpBinding();
binding.MaxReceivedMessageSize = int.MaxValue;
host.AddServiceEndpoint(typeof(IServiceInterface), binding, SERVICE_URL);
Also, I think that you could accomplish this by overriding the OnOpening method of a custom web service host, as per your question. Be aware that the base OnOpening behavior potentially creates endpoints and edits binding behavior, so you will want to let it do all of that first, before you try to change the binding configurations yourself. But I'm not really sure why you would go to all that trouble...
Easiest way is to configure it in web.config where you can change it later if needed. First create binding configuration as mentioned below in your web.config or app.config
<bindings>
<basicHttpBinding>
<webHttpBinding>
<binding name="Binding_Name" maxReceivedMessageSize="2147483647">
</binding>
</webHttpBinding>
</bindings>
Then mention the same in your service endpoint as written below
<services>
<service behaviorConfiguration="ServiceBehaviour" name="Servicename">
<endpoint address="" binding="webHttpBinding" bindingConfiguration="Binding_Name" contract="Contractname" />
</service>
</services>
I'm publishing a service with a MEX endpoint for metadata exchange and I'm using the code below to discover it and get the metadata information
DiscoveryClient discoveryClient = new DiscoveryClient(new UdpDiscoveryEndpoint());
FindCriteria findCriteria = FindCriteria.CreateMetadataExchangeEndpointCriteria(ContractType);
findCriteria.Duration = TimeSpan.FromSeconds(15);
findCriteria.MaxResults = 1;// MaxResults;
FindResponse result = discoveryClient.Find(findCriteria);
discoveryClient.Close();
ServiceEndpointCollection eps = MetadataResolver.Resolve(ContractType, result.Endpoints[0].Address);
return eps[0].Binding;
When I get the metadata information in my client the binding information (OpenTimeout,
ReceiveTimeout and SendTimeout) is back to its default values.
Here is the binding information in the host
<binding name="MyServiceBinding" closeTimeout="00:05:00" openTimeout="00:05:00"
receiveTimeout="23:50:00" sendTimeout="00:05:00" maxReceivedMessageSize="50000000">
<readerQuotas maxStringContentLength="50000000" maxArrayLength="50000000" />
<reliableSession ordered="true" inactivityTimeout="00:01:00" enabled="false" />
<security mode="None" />
</binding>
here is another question i've found that is almost the same as mine.
WCF Service Binding taking default values instead of custom values
I would like to know if I'm doing something wrong or if I misunderstood the concept of metadata exchange.
What I'm trying to do is send all the info necessary to my clients so they can auto config them self and do not have any hard code configuration.
I don't think you're doing anything wrong - you're just expecting too much from the metadata exchange.
The purpose of MEX is to be able to discover new services programmatically, and create client-side proxies for those services. For this, there's the WSDL - basically anything contained in the WSDL is part of the metadata exchange:
service contract / service methods
parameters needed for those service methods
data type declarations in XML schema for the data types used
additional service related information like bindings used etc.
But MEX does not contain all WCF specific configuration settings - which is what you've discovered. MEX will create a functioning client-side proxy - but it never had the intention of transporting all configuration settings from the server to the client. You'll need to hand-code this yourself, on the client side.
We currently support several WCF services running in a load balanced environment. In the past, we have used wsHttpBinding and set establishSecurityContext to false to allow the service to work properly with our load balancer.
An issue we have ran into is that the wsHttpBinding encrypts the return results by default and, apparently, cannot be turned off. This causes issues with the Riverbed compression appliance we have on our network - i.e. the encrypted data does not compress very well (or at all).
Now we're attempting to make use of the basicHttpBinding since it does not encrypt the data by default. We have two requirements:
Work with the load balancer - this appears to be possibly by using setting the keepAliveEnabled to false. This requires the use of a custom binding. For example:
<customBinding>
<binding name="NewBinding0">
<httpTransport authenticationScheme="Ntlm" **keepAliveEnabled="false"** />
</binding>
</customBinding>
Passes User Credentials - this appears to be possible by setting the security mode to TransportCredentialOnly. This is available with the basicHttpBinding. For example:
<basicHttpBinding>
<binding name="NewBinding1">
<security **mode="TransportCredentialOnly"** />
</binding>
</basicHttpBinding>
So now for my actual question :-)... How/Is it possible to combine the above two requirements into a single custom binding? What is the equivalent of #2 above for a custom binding? How can I get it to pass the user credentials?
Thanks!
It turns out I was able to do what I wanted with the custom binding using the following binding configuration:
<customBinding>
<binding name="NewBinding0">
<httpTransport authenticationScheme="Ntlm" keepAliveEnabled="false" />
</binding>
</customBinding>
Then, on the client side, I could use the following code to get the identity of the application pool the WCF service was running under (in IIS) as well as the identity of the user who actually called the WCF service:
public string GetData(int value)
{
var callingUser = string.Empty;
var appPoolUser = WindowsIdentity.GetCurrent().Name;
var identities =
OperationContext.Current.ServiceSecurityContext.AuthorizationContext.Properties["Identities"] as
IList<IIdentity>;
if (identities != null)
{
var result = from i in identities
where i.AuthenticationType == "NTLM"
select new { i.Name };
if (result.Count() > 0)
{
callingUser = result.First().Name;
}
}
return string.Format("Value Entered: {0}; AppPool User: {1}; Calling User: {2}", value,
appPoolUser, callingUser);
}
I tested the above code in a load balanced environment, for Requirement #1, and everything seemed to run just fine. The tests simulated a 100-user load for 10 minutes in a load balanced environment. We took one of the load balanced servers down during the test and everything continued to run as expected (i.e. no exceptions were thrown during the tests nor did any identities come back incorrectly).
The code above is the key piece, for Requirement #2, that I was missing - i.e. I didn't realize until this research that WCF would give you multiple identities.
Also, using this configuration, the results of the WCF call is not encrypted (which is what we wanted). So, I think this configuration will work for our situation just fine.
I'm having difficulty connecting to a 3rd party WSE 3.0 web service from a WCF client. I have implemented the custom binding class as indicated in this KB article:
http://msdn.microsoft.com/en-us/library/ms734745.aspx
The problem seems to have to do with the security assertion used by the web service - UsernameOverTransport.
When I attempt to call a method, I get the following exception:
System.InvalidOperationException: The
'WseHttpBinding'.'[namespace]'
binding for the
'MyWebServiceSoap'.'[namespace]'
contract is configured with an
authentication mode that requires
transport level integrity and
confidentiality. However the transport
cannot provide integrity and
confidentiality..
It is expecting a username, password, and CN number. In the example code supplied to us by the vendor, these credentials are bundled in a Microsoft.Web.Services3.Security.Tokens.UsernameToken. Here's the example supplied by the vendor:
MyWebServiceWse proxy = new MyWebServiceWse();
UsernameToken token = new UsernameToken("Username", "password", PasswordOption.SendPlainText);
token.Id = "<supplied CN Number>";
proxy.SetClientCredential(token);
proxy.SetPolicy(new Policy(new UsernameOverTransportAssertion(), new RequireActionHeaderAssertion()));
MyObject mo = proxy.MyMethod();
This works fine from a 2.0 app w/ WSE 3.0 installed. Here is a snippet of the code from my WCF client:
EndpointAddress address = new EndpointAddress(new Uri("<web service uri here>"));
WseHttpBinding binding = new WseHttpBinding(); // This is the custom binding I created per the MS KB article
binding.SecurityAssertion = WseSecurityAssertion.UsernameOverTransport;
binding.EstablishSecurityContext = false;
// Not sure about the value of either of these next two
binding.RequireDerivedKeys = true;
binding.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;
MembershipServiceSoapClient proxy = new MembershipServiceSoapClient(binding, address);
// This is where I believe the problem lies – I can’t seem to properly setup the security credentials the web service is expecting
proxy.ClientCredentials.UserName.UserName = "username";
proxy.ClientCredentials.UserName.Password = "pwd";
// How do I supply the CN number?
MyObject mo = proxy.MyMethod(); // this throws the exception
I've scoured the web looking for an answer to this question. Some sources get me close (like the MS KB article), but I can't seem to get over the hump. Can someone help me out?
I had success in a similar case with the following binding configuration:
<bindings>
<customBinding>
<binding name="FNCEWS40MTOMBinding">
<security enableUnsecuredResponse="true" authenticationMode="UserNameOverTransport"
allowInsecureTransport="true" messageProtectionOrder="SignBeforeEncrypt">
<secureConversationBootstrap />
</security>
<mtomMessageEncoding messageVersion="Soap12WSAddressingAugust2004"
maxBufferSize="2147483647" />
<httpTransport maxReceivedMessageSize="2147483647" />
</binding>
</customBinding>
</bindings>
Hope it works for you too.
The error message is refering to Transport Level Security, this usually means https.
You have not shown your configuration files. But I am guessing that you have configured security to be transport (or it is required as a consiquence of another choice) and used an address that is http instead of https.
This has happened a couple of times to me know. If I add to many OperationContract's to a ServiceContract, the WCF Test Client app throws an exception:
"Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata."
In the details it continues:
Error: Cannot obtain Metadata from . The request failed with HTTP status 400: Bad Request.
If I remove a couple of operation contracts then everything is fine. Outside of the test client is also fine.
Could you be more specific about what kinds of operations you have to remove from the service contract to make it work?
Here are some known limitations in the WcfTestClient.exe tool that comes with the .NET Framework 3.5 SDK. Note that all of these issues have been fixed in the version that ships with .NET 3.5 SP1.
The client does not maintain a session with the invoked service. All calls are made on new proxy instances
The auto-generated configuration file for the client proxy can be viewed but not edited
Services using the XML Serializer instead of of the Data Contract Serializer cannot be invoked
Services using Message Contracts cannot be invoked
Thanks for the responses.
These were the offending lines:
<OperationContract(), FaultContract(GetType(WcfService.Common.DefaultFaultContract))> _
Function GetJobSubTypesForJobTypeList(ByVal jobTypeList As Dictionary(Of Integer, String)) As List(Of JobSubTypeOfJobTypeDTO)
<OperationContract(), FaultContract(GetType(WcfService.Common.DefaultFaultContract))> _
Function GetActivityTypesForJobTypeList(ByVal jobTypeList As Dictionary(Of Integer, String)) As List(Of ActivityTypeOfJobTypeDTO)
It turned out that we were missing setters in the return types (DTO) and a default constructor.
This is one of the weirdest problems I've come across. You might have to review your code and look out for problems such as:
Private _NetPay As Boolean
<DataMember()> _
Public Property NetPay() As Boolean
Get
Return _Amount = 0
End Get
Set(ByVal value As Boolean)
_NetPay = value
End Set
End Property
I had defined a DataMember as the above. Notice the return statment. It is trying to return a computed value. I removed this data member; it worked fine.
This is what i had to add to my devenv.exe.config in order to get my WCF Test Client to work with a very large service. I then had to restart my IDE. This may not be what you are looking for, but i hope it helps.
<system.serviceModel>
<bindings>
<customBinding>
<binding name="MyBinding">
<textMessageEncoding>
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
</textMessageEncoding>
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"/>
</binding>
</customBinding>
</bindings>
<client>
<endpoint binding="customBinding" bindingConfiguration="MyBinding" contract="IMetadataExchange" name="http"/>
</client>
</system.serviceModel>