I have strange problem with WCF service. I use pollingDuplexBinding and Silverlight client.
Binding was registred by this code in web.config
<bindingElementExtensions>
<add name="pollingDuplex" type="System.ServiceModel.Configuration.PollingDuplexElement, System.ServiceModel.PollingDuplex" />
</bindingElementExtensions>
On first call everything is ok - service returns data fast. But second call executes more than 5 mitutes. If I set big timeouts, result will be returned to client, else it throws TimeoutException. WCF method I'm calling does nothing - just returns short string.
WCF tracing says, that second service call just coming 5 minutes later than client calls this method, and executes quickly.
I use these service attributes:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
It's client code
var binding = new PollingDuplexHttpBinding(PollingDuplexMode.SingleMessagePerPoll);
var address = new EndpointAddress("/SportService.svc");
_proxy = new SportDuplexClient(binding, address);
i hade same problem, i solve it in this way :
just set aspNetCompatibilityEnabled="false" to false in web.config file
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
or set sessionState mode="Off" in web.config
<system.web>
<sessionState mode="Off" />
</system.web>
in both way my problem will solved...
Related
We have a WCF service that listens to an Azure servicebus queue using the NetMessagingBinding. However we are finding that sometimes the service seems to stop being notified when messages arrive, ie we see the queue build up but none of our instances process the messages.
If we then reboot the instances they immediately start receiving messages from the queue again.
The code which opens the WCF service in our worker role:
var endpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(ICacheKeyExchangeWithSession)))
{
Address = new EndpointAddress(new Uri(baseAddress + QueueNames.Cache)),
Binding = new NetMessagingBinding(),
};
var endpointBehavior = new TransportClientEndpointBehavior
{
TokenProvider = TokenProvider.CreateSharedSecretTokenProvider(id, secret),
};
endpoint.EndpointBehaviors.Add(endpointBehavior);
host = new ServiceHost(typeof(DataService), new Uri[] { });
host.AddServiceEndpoint(endpoint);
host.Open();
and we have no specific config in the app.config for the NetMessagingBinding:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<extensions>
<behaviorExtensions>
<add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</behaviorExtensions>
<bindingElementExtensions>
<add name="netMessagingTransport" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingTransportExtensionElement, Microsoft.ServiceBus, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingElementExtensions>
<bindingExtensions>
<add name="netMessagingBinding" type="Microsoft.ServiceBus.Messaging.Configuration.NetMessagingBindingCollectionElement, Microsoft.ServiceBus, Version=1.8.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</bindingExtensions>
</extensions>
</system.serviceModel>
Any ideas?
From what you've described, it sounds like you may be victim of your IIS configuration: you need to ensure iis isn't configured to automatically recycle your application pool that runs your app. If you don't also have application initialization configured in iis, your service won't restart automatically and resume processing messages
I have a WCF service with a CallbackContract. The service is exposed to a Silverlight client using "pollingDuplexHttpBinding"
When the Silverlight client is "dead" and the service calls a callback operation, it gets a timeout exception after one minute.
How can I set this timeout to be different?
Thanks,
Elad
There is a nice article in MSDN related to configuring PollingDuplexHttpBinding:
//Inactivity timeout
PollingDuplexHttpBinding binding = new PollingDuplexHttpBinding();
//Get default inactivity timeout
TimeSpan defaultInactivityTimeOut = binding.InactivityTimeout;
//Returns default timeout in minutes: 10
string txtDefaultInactivityTimeOut = defaultInactivityTimeOut.Minutes.ToString();
//Set new inactivity timeout
TimeSpan newInactivityTimeOut = new TimeSpan(0, 5, 0);
binding.InactivityTimeout = newInactivityTimeOut;
UPDATE: Under 'To use PollingDuplexHttpBinding' paragraph of 'How to: Build a Duplex Service for a Silverlight Client' there is web.config based example configuring PollingDuplexHttpBinding.
Hope, this will help.
So it seems that the "SendTimeout" attribute of PollingDuplexHttpBinding does the job:
<extensions>
<bindingExtensions>
<add name="pollingDuplexHttpBinding" type="System.ServiceModel.Configuration.PollingDuplexHttpBindingCollectionElement, System.ServiceModel.PollingDuplex, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</bindingExtensions>
</extensions>
<bindings>
<pollingDuplexHttpBinding>
<binding name="myPollingDuplex" sendTimeout="00:00:05"/>
</pollingDuplexHttpBinding>
</bindings>
<services>
<service name="Kodak.Pgy.Server.Event.WCFService.EventService" behaviorConfiguration="EventBehavior">
<!--For duplex communication with the service from silverlight client-->
<endpoint address="/for-silverlight" binding="pollingDuplexHttpBinding" bindingConfiguration="myPollingDuplex" contract="IEventService"/>
</service>
</services>
Relevant Service Code:
[WebGet(BodyStyle = WebMessageBodyStyle.WrappedResponse, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate="products")]
public Product[] GetAllProduct()
{
return ProductProvider.Instance.GetAllProducts();
}
[OperationContract]
Product[] GetAllProduct();
Relevant Configuration Code:
<?xml version="1.0"?>
<configuration>
<connectionStrings>
<add name="TestEntities" connectionString="metadata=res://*/ProductEntityDataModel.csdl|res://*/ProductEntityDataModel.ssdl|res://*/ProductEntityDataModel.msl;provider=System.Data.SqlClient;provider connection string="data source=PC\MSSQL2008;initial catalog=Test;integrated security=True;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
<system.serviceModel>
<services>
<service name="Service.Default">
<endpoint address="http://localhost:1651/Default.svc" binding="webHttpBinding" contract="Service.IDefault"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
<system.web>
<compilation debug="true"/>
</system.web>
</configuration>
Relevant Fiddler Request
I've had issues with URITemplate in the past. Can you try:
[WebGet(BodyStyle=WebMessageBodyStyle.WrappedResponse, ResponseFormat=WebMessageFormat.Json)]
public Product[] products()
{
return ProductProvider.Instance.GetAllProducts();
}
[OperationContract]
Product[] products();
This may because of a DateTime type property in your class which is DateTime.MinValue (0001-01-01) by default.
I had exactly the same problem and resolved it by setting the date to a bigger value.
Also you should pay attention to any property which can not directly be serialized to JSON, such as TimeSpan, DateTimeOffset etc.
we have same problem. I found something relevant answer here:
WCF DataContractSerializer has a limit of 65536 object in the object graph
Hope it would help.
I had a similar problem with Fiddler (v2.3.9.3) with a service using a BasicHttpBinding; I was able to fix it by changing the transferMode on the binding to Streamed (the default is Buffered), and then put Fiddler in Streaming Mode (make sure the "Stream" button on the toolbar is in the selected/pressed state).
# Chris
I just ran into this and the problem was the object graph limit mentioned in the link that user72213 posted.
Modifying this limit using the ServiceBehaviorAttribute.MaxItemsInObjectGraph property did the trick for me.
You can also try the <dataContractSerializer>'s maxItemsInObjectGraph attribute, but using the attribute was more convenient in my case.
I was getting this problem when returned dateTime object was null. It runs fine while debugging and gives problems while desalinizing.
One way is to make your dateTime null able DateTime? and it will be deserialized correctly.
Hope helpful for someone.
In a solution, I added a "WCF Service Library". No problem with the default method. I added one :
In the interface :
[ServiceContract]
public interface ISecurityAccessService
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
[OperationContract]
CompositeUser ListUser();
}
[DataContract]
public class CompositeUser
{
List<User> _listUser = new List<User>();
[DataMember]
public List<User> ListUser
{
get { return _listUser; }
set { _listUser = value; }
}
}
The interface implementation, the dataaccess iw working, I tested the DataService and no problem.
public class SecurityAccessService : ISecurityAccessService
{
public CompositeUser ListUser()
{
DataAccess.DataService service = new DataAccess.DataService();
CompositeUser compositeUser = new CompositeUser();
compositeUser.ListUser = service.ListUser();
return compositeUser;
}
}
When I execute and try to invoke, I receive this error message :
*An error occurred while receiving the HTTP response to http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary/ISecurityAccessService/. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down). See server logs for more details.*
The App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<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.serviceModel>
<services>
<service name="WcfServiceLibrary.SecurityAccessService">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8732/Design_Time_Addresses/WcfServiceLibrary/ISecurityAccessService/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address ="" binding="wsHttpBinding" contract="WcfServiceLibrary.ISecurityAccessService">
<!--
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.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- 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 -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="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>
</system.serviceModel>
</configuration>
Update 1
I made a working sample with database access. I just don't understand something in the "PersonService" class, why I have to make this loop. Solution is welcome.
Download 40ko .rar full example
your User class needs to be marked with the DataContract attribute and its methods with the DataMember attribute. It may also need to be marked as a KnownType in the CompositeUser class so that it is included in the types for the service. You can do that like so:
[DataContract]
[KnownType(typeof(User))]
public class CompositeUser
{
...
}
you'll be able to tell what the issue is from the logs. Either you'll get a 'cannot be serialized' message, in which case you need to add the [DataContract] attribute or it will be 'type was not expected' in which case you'll also need to add the [KnownType] attribute
If you enable tracing in your service you'll be able to get more details of what the problem was. Add something like this in the config file:
<configuration>
<system.diagnostics>
<trace autoflush="true"/>
<sources>
<source name="System.ServiceModel" switchValue="Verbose">
<listeners>
<add name="sdt" type="System.Diagnostics.XmlWriterTraceListener" initializeData="D:\wcfLog.svcLog"/>
</listeners>
</source>
</sources>
</system.diagnostics>
</configuration>
also setting <serviceDebug includeExceptionDetailInFaults="True" />
will allow more detail about the error to be returned in the service exception which might also help.
EDIT
From the comments below it seems the User class is a Linq to SQL generated class. I don't think you should be sending this class across the wire. WCF deals with messages not in serializing types with behaviour, so you should create a DTO which represents the data in your User class that will be needed on the client and send this DTO out from the service contract. Even if you do send the User class as it is, when it gets to the client it won't have the context to still be connected to the DB.
I faced this problem again today. A long time ago I had the same problem, but I had forgotten the cause and it took me some time to sort it out toady.
In my case, it was a looping serialization problem. One table has a column which is a foreign key to another column in the same table. So all I had to do was to click the work surface of the dbml file and change the Serialization Mode to Unidirectional.
If yours is a Linq to Sql situation, and the error message is the one shown above, you might want to check whether it is the same cause as mine.
I have 2 WCF services and a client which calls the method of 1st WCF service, and that method consequently calls the method of 2nd WCF service. The method of 2nd WCF service rises a generic fault exception, I need that this exception will be normally 'delivered' to my client through the 1st service. The 1st WCF service normally gets that generic exception with some Action "http://SomeNamespace" in exception message body. When the 1st service rethrow this exception to client, the client gets simple FaultException instead of FaultException1. I think the problem is inAction` which contains a namespace which is not acceptable for the client, and that's why the client is not able to get generic exception. There is a WCF Exception Shielding in 1st WCF service. Below are the configuration code and the handler code.
Please help me and advise the best way to change the action of exception that the client will be able to get it normally.
Here is the config:
<exceptionHandling>
<exceptionPolicies>
<add name="WCF Exception Shielding">
<exceptionTypes>
<add type="System.ServiceModel.FaultException`1[[Sample.SomeFaultContract, Sample, PublicKeyToken=769e6b46280078d4]], System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
postHandlingAction="ThrowNewException" name="SomeFaultContract">
<exceptionHandlers>
<add faultContractType="Sample.SomeFaultContract, Sample, PublicKeyToken=769e6b46280078d4"
type="Helper.ServiceFaultContractHandler, Logger, PublicKeyToken=769e6b46280078d4"
name="Fault Contract Exception Handler" />
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
</exceptionHandling>
And the handler part is:
public class ServiceFaultContractHandler : IExceptionHandler
{
public ServiceFaultContractHandler(NameValueCollection ignore) { }
public Exception HandleException(Exception exception, Guid correlationID)
{
}
}
Thank you in advance.
Aram
In order to get the details of the exception, you should set the includeExceptionDetailInFaults property to true in the service behavior.
Below is a sample:
<behaviors>
<serviceBehaviors>
<behavior name="WCFServicesName">
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>