Wcf ignore MaxItemsInObjectGraph value - c#

Our WCF service has the following exception:
Maximum number of items that can be serialized or deserialized in an object graph is '32767'. Change the object graph or increase the MaxItemsInObjectGraph quota.
We change the config to:
<behavior name="large">
<dataContractSerializer maxItemsInObjectGraph="214783647"/>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
But no change.
In debug mode when the service host is open the value of the DataContractSerializer is 214783647 and the exception is still occur.
Changing the value programmaticly doesn't help.
Add an attribute of ServiceBehavior on the service doesn't help.
Change the machine.config like here - doesn't help.
Any ideas?
Thanks.

You may want to confirm that the error is not coming from the other side (client) of the transaction.
One way to verify, is to configure and enable WCF diagnostic event tracing and message logging, then rerun the test transaction and review the service trace log file. The following link demonstrates how to enable tracing and message logging.
http://msdn.microsoft.com/en-us/library/ms751526.aspx

Thanks to my college the problem solved with removing ReferencePreservingDataContractFormat attribute, we think it's because this attribute create it's own DataContractSerializer that ignore the configuration.
More details

Related

Not able to get Exception message from SOAP call using service reference .net

I am using service reference in .NET to call a third party carrier API i.e. ESTES. you can find the wsdl here. now whenever I call it from the code and there are some errors it just throws a FaultException and exception message as GeneralErrorMsg or SchemavalidationError with no meaningful messages. I do get the meaningful messages when I run it in SOAP UI tool but not from .Net code.
Following are some link of images of exception. FYI innerexception is null
Exception Stack Trace Image
Exception Data Property Image
Below is the response that I get, when I run the API using SOAPUI. FYI this is third party API and not ours I am just calling their API
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>GeneralErrorMsg</faultstring>
<detail>
<bol:generalError xmlns:bol="http://ws.estesexpress.com/bol">
<bol:error>
<bol:code>BOL0193</bol:code>
<bol:message>We cannot automatically assign a PRO number if the shipping address is not serviced directly by Estes. Please uncheck the "Assign PRO #" box. Questions? Feel free to call your <a href="/WebApp/TerminalList/"> local terminal</a>.</bol:message>
</bol:error>
<bol:error>
<bol:code>BOL0101</bol:code>
<bol:message>Invalid state/zip combination</bol:message>
</bol:error>
</bol:generalError>
</detail>
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
Please help me guys its really giving me hard time.
Try adding service behavior in web.config file where your service is hosted
<behavior name="faultBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
But this has some other down side in terms of security.

How to control number of inbound connections on webHttpBinding service?

I have a standard Web Service that processes JSON requests via an webHttpBinding. I am trying to find out whether there is a limit on how many concurrent connections it can handle and how to control it. Can't find anything. I am missing something simple or some setting?
Here is a skeleton of my service:
[ServiceContract]
public interface IMyService {...}
[ServiceErrorBehavior(typeof(ErrorHandler))]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MyService : IMyService {...}
I have some suggestion for this, but this will not be direct config related change. Hold on and read this.
In WCF, there is InstanceContextMode and ConcurrencyMode properties defined for ServiceBehavior. These parameters are configurable only within the service code, and not in XML configuration, because they relate to the runtime behavior of the service and the service developer should be aware of their values. The InstanceContextMode parameter determines how many instances of the service have to be created by the WCF runtime. The possible values are:
PerCall: a new InstanceContext object is created for each call.
PerSession: a new InstanceContext object is created for each session. If the channel does not create a session this value behaves as if it were PerCall.This is the default value.
Single: only one InstanceContext object is used for all incoming calls and is not recycled subsequent to the calls. If a service object does not exist, one is created.
More helpful Blog
Use WCF Service Throttling to control the service.
<behaviors>
<serviceBehaviors>
<behavior name="Throttled">
<serviceThrottling
maxConcurrentCalls="1"
maxConcurrentSessions="1"
maxConcurrentInstances="1"
/>
</behavior>
</serviceBehaviors>
</behaviors>
Always remember that service behaviors do not override limits defined in the host (or binding). For example when using webHttpBinding the default IIS Maximum Concurrent Connections would likely need to be changed for large concurrency values.
Turns out it has more to do with threading than anything else. The default ASP.NET settings are pretty conservative, so you have to hike them up. Once I did that, the concurrent connections bottleneck completely disappeared.
Make sure you have the following in the appropriate machine.config (not web.config):
<configuration>
<system.net>
<connectionManagement>
<add address="*" maxconnection="100" />
</connectionManagement>
</system.net>
<system.web>
<processModel
autoConfig="true"
maxWorkerThreads = "100"
maxIoThreads = "100"
minWorkerThreads = "50"
minIoThreads = "50"
/>
<httpRuntime
minFreeThreads="176"
minLocalRequestFreeThreads="152"
/>
</system.web>
</configuration>
I took all this info from Tuning IIS article by Stuart Brierley. The only thing I changed significantly from his recommendations is maxConnection value.

How do I add TLS to a WCF service?

I've been trying to add TLS to a WCF service, I've created.
Everything is OK until I try to access the service through https instead of http.
When adding the wcf service to the wcf test client, I get this:
Error: Cannot obtain Metadata from [THELINK] 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. For help enabling metadata publishing, please refer to the
MSDN documentation at [an MS link] Exchange Error URI: [THELINK]
Metadata contains a reference that cannot be resolved: '[THELINK]'.
There was no endpoint listening at [THELINK] that could accept the
message. This is often caused by an incorrect address or SOAP action.
See InnerException, if present, for more details. The remote server
returned an error: (403) Forbidden.HTTP GET Error URI: [THELINK]
There was an error downloading '[THELINK]'. The request failed with
HTTP status 403: Forbidden.
Sorry about the link replacing, but I'm new and I don't have the reputation, it seems :)
Regards,
Morten
do you have a
<behaviors>
<serviceBehaviors>
<behavior name="YourSerivceBehaviourName">
<serviceMetadata httpsGetEnabled="true" /> <-- this bit ?
...
...
being referenced by your
<service name="...." behaviorConfiguration="YourSerivceBehaviourName">
or a
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
in your web.config?
the Test client will also moan if the certificate isn't a real one I have found.. ie a self certed one for testing.
but the 403 seems to suggest that whatever credentials you are supplying are incorrect, what is the clientCredentialType set to in the SSL binding?
and what happens if you hit the link in a browser with customerrors off..
this might give you some more useful information

Can you mimic an existing service in WCF?

We have a 3rd party vendor service and an in-house service to communicate with it. Everything works perfectly with our in-house service, but I've been asked to write a fall back clone of our vendor's service. The intention is to be able to run up our clone, swap-out the client end-point and allow our in-house service to continue testing against the clone.
Is it possible to recreate/mimic a service such that an existing client can communicate with it (without modification) as if it were the original service?
So far I’ve tried 3 things and none of them work.
1st approach
Create a simple service, reference the 3rd party service to gain access to the custom types and mimic the [operation Contract]’s.
When I try to communicate with this service I get the following error.
A first chance exception of type 'System.ServiceModel.ActionNotSupportedException' occurred in System.ServiceModel.dll
Additional information: The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
There is no security requirements as we are using basic http (no ssl). The service model portion of the config file and the service behaviour class attributes are below:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="SimpleBinding" />
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="cloneBehavior" name="MyClone">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="SimpleBinding"
contract="MyService.IMyService" />
<host>
<baseAddresses>
<add baseAddress="http://localhost/clone/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="cloneBehavior">
<serviceMetadata httpGetEnabled="True" httpGetUrl="http://localhost/clone/mex" />
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
and the service behaviour
[ServiceBehavior(Name = "CloneService",
ConfigurationName = "MyClone",
InstanceContextMode = InstanceContextMode.PerCall,
AddressFilterMode = AddressFilterMode.Any)]
public class MyService : IMyService
{
Everything looks good and I have come to my first dead end.
2nd approach
Get rid of my interface/service contract and inherit directly from the interface generated in the reference.cs file.
When I run this service up, I get the following error
System.InvalidOperationException: The operations myMethodA and myMethodB have the same action (). Every operation must have a unique action value.
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ActionDemuxer.Add(String action, DispatchOperationRuntime operation)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime..ctor(DispatchRuntime dispatch)
at System.ServiceModel.Dispatcher.DispatchRuntime.GetRuntimeCore()
at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpened()
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)
Taking a look at the generated interface for this method, they are all decorated with the following attribute:
[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="*")]
My understanding from msdn is that WCF defaults to adding a unique action of the pattern <namespace>/<service>/<operation>[Response].
If I try setting the action to * then I can hit the service (as expected with the catch all / unmatched message handler), but I can't hit a specific method.
Nevertheless, manually making all the actions unique (and conforming to the above pattern), give this error:
The contract ‘IMyService’ in client configuration does not match the name in service contract, or there is no valid method in this contract.
…
I have clearly defined methods in the service contract and have come to a second dead end.
3rd approach
Using the wsdl.exe tool to generate a service from the wsdl. I followed the instructions from this SO post to generate an interface and inherit from it.
I’ve also tried generating the service itself by using the clientWsdl.wsdl /l:CS /server command and following the instructions in this post.
After tidying up the generated code and running it up, I’m back to my original error:
A first chance exception of type 'System.ServiceModel.ActionNotSupportedException' occurred in System.ServiceModel.dll
Additional information: The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).
At each attempt I have double checked all the config settings and updated the contract at each stage.
At this stage I'm wondering if it's even possible.
Were you ever able to mimic the service using WCF? I find myself in a similar situation where I've been tasked to write some integration tests where our method makes a call to a vendor's web service. I would have preferred to leverage Moq to write proper unit tests, but I'm constrained by 1) not being allowed to change the signature of the method that I'm testing, and 2) not really knowing anything about the web service itself except for what we send to the service and its expected response.
#jparram's suggestion was my next approach.
Note: I would have preferred to have posted this as a comment seeing that I'm not really answering your question.
If I understand your scenario, I would create wrapper service that decides which service to call. It sounds like that's what you want to do with Scenario 1. So, your client would always be calling your wrapper service, and your wrapper service would map the inputs to the required inputs of your 3rd party service or your back up service.
The error you received sounds like an issue in the generation of the proxy client where the "Action" is not getting mapped. Take a look at the generated proxy code from a known working configuration and compare it to what is in your scenario 1.
Edit
Compare the generated proxy client of your service and the 'real' service. The complaint about the Action = "" is probably due to the:
[System.ServiceModel.OperationContractAttribute(Action="", ReplyAction="")]
On your client not getting mapped to the corresponding operation.

Max Outbound connections

I have an application written in c# on .NET 4.0 which needs to make multiple web service requests. The web service requests vary in nature but are mostly requesting information.
The Types involved is a derivative of System.ServiceModel.ClientBase
The connection is setup in code and uses types such as BasicHttpBinding, EndpointAddress, and CustomBinding to name a few.
How can I determine the max number of concurrent requests that can be made on the derivative of the ClientBase?
I've not been able to find any property that pertains to MaxConnections but I do come across things like NetTcpBinding.MaxConnections and ConnectionManagementElement.MaxConnection but neither of these seem compatible with my leveraged APIs. Either I'm missing how to use them, this isn't available or I don't know where to look.
WCF is an abstraction on core networking concepts. For HTTP bindings, it falls under the ServicePoint configuration which determines things like your HTTP concurrent connection limits.
You want ServicePointManager.DefaultConnectionLimit for HTTP:
http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.defaultconnectionlimit.aspx
You can also do this via your config file:
http://msdn.microsoft.com/en-us/library/fb6y0fyc.aspx
This would be in the binding configuration section of the service host's .config file. Depending on the binding being used, you can set things like maxConcurrentCalls and maxConcurrentSessions, there are usually default limits for them imposed by WCF.
Real life example:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehaviorBasicHttp">
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentSessions="1000" maxConcurrentInstances="1000"/>
<serviceMetadata />
</behavior>
</system.serviceModel>
Or in code behind, something like this:
ServiceHost host = new ServiceHost(typeof(MyService));
ServiceThrottlingBehavior throttleBehavior = new ServiceThrottlingBehavior
{
MaxConcurrentCalls = 40,
MaxConcurrentInstances = 20,
MaxConcurrentSessions = 20,
};
host.Description.Behaviors.Add(throttleBehavior);
host.Open();
Taken from here: WCF: How do I add a ServiceThrottlingBehavior to a WCF Service?

Categories

Resources