The underlying connection was closed: The connection was closed unexpectedly - c#

This exception is consistently thrown on a SOAP Request which takes almost three minutes to receive and is 2.25 megs in size.
When scouring the web I find all sorts of posts which all seem to be about setting headers on the Request, some want me to not send the "Expect:" header, some want me to send the "Keep-Alive:" header, but irregardless of the headers I send I still get this pesky error. I don't believe that setting any headers is my answer, because I can recreate the exact same request using "curl" and a response does eventually come back with no problems what-so-ever.
My <httpRuntime maxRequestLength="409600" executionTimeout="900"/>.
I feel as if I'm running out of options. If anyone can provide any assistance I would be most grateful. A few other things to note would be that the server I'm Requesting data from is out of my hands, also these requests are over https and other requests with smaller responses work flawlessly.
Thanks

You tagged the post as .NET35, so are you using WCF?
If so, here is an example of the App.config we use for large data sets:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="8388608" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:1602/EndPoint.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding" contract="IEndPointContract" name="EndPoint" behaviorConfiguration="EndpointBehaviour" />
</client>
<behaviors>
<endpointBehaviors>
<behavior name="EndpointBehaviour">
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>

I hope it's not too late for answering this question.
Try adding the following attribute on the definition of your contract interface: [ServiceKnownType(typeof(ReturnClass))]
For more generic solution that allows returning polymorphic classes please refer to this post:
http://www.goeleven.com/blog/entryDetail.aspx?entry=45

If you are using dbml instead of edmx you will get this( The underlying connection was closed: The connection was closed unexpectedly.) as dbml will not return serialisable data it needs datacontract so go to properties of dbml file and change the Serialization mode to unidirectional.

Have you tried the sugestion of this Blog Post? The problem will most probably lie in the TCP/HTTP stack implementation of .NET .

i got this error because my datatransfereobjects refered to each other in an recursive manner.
For example:
Customer-> (has) -> Rating
Rating-> (belong to) -> Customer
so you have to remove cycles.
[DataContract]
public class Rating
{
private Customer _customer;
//[DataMember] // <- EITHER HERE
public Customer Customer
{
get { return _customer; }
set { _customer = value; }
}
}
[DataContract]
public class Customer
{
private long _customerID;
[DataMember]
public long CustomerID
{
get { return _customerID; }
set { _customerID = value; }
}
[DataMember] // <- OR HERE
public Rating Rating
{
get { return _rating; }
set { _rating = value; }
}
}

Tried several ways to get rid of this error message until I found this solution:
http://kiranpatils.wordpress.com/2008/09/22/the-underlying-connection-was-closed-the-connection-was-closed-unexpectedly-while-returning-data-table-from-wcf-service/
You may change your List<> to DataSet. I suspect DataSet can handle much amount of data than the List<>.
Hope it helps.

I've got the same issue, and after deep investigations I found this article:
Merrick Chaffer's Blog
It was all related to setting the "dataContractSerializer" for both client and server.
Hope this to be helpful.

I have added another field, but didn't have a set on the property.
That was my solution for the same error.
[DataMember]
public bool HasValue
{
get { return true; }
set { }//adding this line made the solution.
}

This is a generic error raised if there is an internal error.
Try adding tracing here: http://msdn.microsoft.com/en-us/library/ms732023(v=vs.110).aspx
You will see the full log then.

For WCF with EF, just add the following code in the context class.
base.Configuration.ProxyCreationEnabled = false;

Related

Awaiting a service task gets TaskCanceledException: A task was canceled

I have one app (UWP - Win10) and a Windows service.
The service is running in background, and they were both developed in C#. "callAsync" is the method on the service. I am using await to call it on the client.
var obj = await callAsync(10);
The problem is:
If this call takes less than 1min40s (100 seconds), then everything works ok. But if it takes more than 1min40s, then an exception will occur "TaskCanceledException: A task was canceled".
I have search SO and the web but still could not find any indication on how to resolve this "timeout" issue. I have added all the "open/close/receive/send" timeout flags on both app and service app.config, although the exception that is thrown in that case is different.
If I try with a simple delay in the client:
await Task.delay(200000);
it works properly.
This service was added through VS2015 "Add Service Reference". I have also "attached" to the server and the server keeps running and prints in the console before and after logs (to confirm that everything is ok).
What am I missing? What configuration and where do I need to change so that the task can run for more than 1 minute and 40 seconds?
CODE:
Example of Server Pseudo-Code:
Interface File:
[ServiceContract(Namespace="http://.....")]
interface ICom {
[OperationContract]
int call(int val);
}
Service.cs
public ServiceHost serviceHost = null;
public BlaBlaWindowsService()
{
ServiceName = "BlaBlaWindowsService";
}
public static void Main()
{
ServiceBase.Run(new BlaBlaWindowsService());
}
protected override void OnStart(string[] args)
{
if (serviceHost != null)
{
serviceHost.Close();
}
serviceHost = new ServiceHost(typeof(BlaBlaService));
serviceHost.Open();
}
protected override void OnStop()
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
}
}
[RunInstaller(true)]
public class ProjectInstaller : Installer
{
private ServiceProcessInstaller process;
private ServiceInstaller service;
public ProjectInstaller()
{
process = new ServiceProcessInstaller();
process.Account = ServiceAccount.LocalSystem;
service = new ServiceInstaller();
service.ServiceName = "BlaBlaWindowsService";
Installers.Add(process);
Installers.Add(service);
}
}
BlaBlaService.cs
class TPAService : ITPAComunication {
public int call(int val) {
System.Threading.Thread.Sleep(200000)
return 0;
}
}
App.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<binding name="ServiceTimeout" closeTimeout="00:10:00" receiveTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00"/>
</bindings>
<services>
<service name="BlaBla.Service.Service"
behaviorConfiguration="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/BlaBla/service"/>
</baseAddresses>
</host>
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="ServiceTimeout"
contract="BlaBla.Service.ICom" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Example of App pseudo-code:
System.ServiceModel.EndpointAddress epa = new System.ServiceModel.EndpointAddress("http://localhost:8000/blabla/service");
System.ServiceModel.BasicHttpBinding bhb = new System.ServiceModel.BasicHttpBinding();
Timespan t = new TimeSpan(0, 10, 0);
bhb.SendTimeout = t; bhb.ReceiveTimeout =t; bhb.OpenTimeout = t; bhb.CloseTimeout = t;
Blabla.ComunicationClient com = new Blabla.ComunicationClient(bhb, epa);
var obj = await com.callAsync(int val);
return obj;
UPDATE #1
This situation only happens in UWP. I have created a similar WinForms project and everything works as expected. This means that it is probably something related to UWP.
After several tries, manipulating different config files, I have not found a solution regarding how to remove the timeout limitation of 100 seconds. To solve this specific problem, I implemented a counter-measure.
What I have found during my tries was:
If the project is in WinForms, everything works as expected. This means, this 100-second-limit, is an UWP "Feature";
If you reduce the SendTimeout to less than 100 seconds, it will throw a TimeoutException with the corresponding timer;
This is not exclusive to the Windows Service. It also happens when comunicating with a SOAP Webservice implementation;
This seems to happen only if you are doing a task the requires "external communication" with a service reference. If you have a "internal" task that takes more than 100 seconds, it works as expected (eg. await Task.delay(250000)).
How I solved this?
After chatting at C# SO channel, #Squiggle suggested a polling approach and that is what I implemented and tested successfully.
These are the steps I took:
I updated the existing service request (call(int val)) to accept a another argument, a Guid, so I could identify which request I wanted to do the "polling";
I created an additional request at the service to InquireAboutCurrentRequest that accepted also accepted a GUID parameter, and returned an int;
I updated the Service Reference at the UWP app with the new request;
I called "await call(val,guid)" with a try catch. I did this because 90% of these calls return in less than 30 seconds*;
In the catch I added an "If" that checked if the exception was a CancelTask, and if was I call "await InquireAboutCurrentRequest(guid)";
This method, at the windows service, keeps checking if the other operation has ended and sleeps every X seconds. Since the total time of the first call can only be at most 2 minutes, I only need to wait 20 seconds;
After that I will deal with the result accordingly, but at least this time I know I have "waited 2 minutes" for the response.
There are other possible solutions such as sockets, which I have not tried, that could work.
* If all the requests take more than 100 seconds, I suggest using the polling approach from the beginning of the requests, instead of waiting for the try/catch.
I'm not sure exactly - but may be better use Task.WhenAll instead of await ?

RESTful web service auto-generate WADL

I have created a RESTful web service in C# and have deployed it to IIS. When I access the service HeadOffice.svc, I have the option to view the WSDL (HeadOffice.svc?wsdl). What I would like to do is have the option of viewing the WADL (e.g. HeadOffice.svc?wadl). Is this possible?
I have read around the place that the general opinion is that this is not the best practice. However, I need the WADL for a school assignment, so any help would be much appreciated.
Suppose you already know that WADL is not standard / not supported widely. And when somebody needs WADL, may be then better to use WS*/SOAP service + WSDL. So your task looks like very strange.
Anyway WADL is not supported "out of the box" in any REST implementation from Microsoft, neither WCF 3.5 Rest Starter Kit, neither WCF 4 REST, and ASP.NET WebAPI.
There are no reliable tools for WADL for .NET.
When your goal is to generate C# client code using WADL, believe me, you will spend more time as writing client code by yourself. And there are better solutions for that.
You can use new classes like HttpClient class or RestSharp or similar libraries to easily manually write your client and it will be even faster then googling for reliable WADL solution for .NET
Similar question on stackoverflow: Restful service in .NET with WADL instead of WSDL
UPDATE - Swagger:
For some years swagger has established itself as such format. You can either start writing service definition using swagger's YAML in the Swagger editor or let generate swagger from existing services, for .NET using Swashbuckle library. The second is something we had with WSDL, and swagger editor let's you generate client and server boilerplates. Regardless you are generating your server or client or not fan of it, swagger is actually a very good contract exchange format for REST service, not ideal but good option.
Why Swagger4Wcf
•Manually writing yaml description for swagger and maintain it especially WCF services are boring.
•There is a nuget package called Swagger4WCF that automatically generates yaml description for swagger 2.0 for each interface matching attributes used by WCF (ServiceContract/OperationContract/WebGet/WebInvoke).
2. How Swagger Works in the Background
Swagger4WCF uses NuPack post build pattern to trigger at build time.
https://www.codeproject.com/Tips/1190360/How-to-setup-a-managed-postbuild-without-scripting
At build time, it will detect assemblies present in output directory, open them with mono.cecil (to reflect assemblies) to generate expected yaml description for swagger 2.0.
Swagger4WCF detects WebGet/WebInvoke to provide Verb/Method in serialization style in yaml.
Steps to implement Swagger in your application:
Install SwaggerWcf package
Configure WCF routes
We have to add the route in the Application_Start method inside Global.asax
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Add(new ServiceRoute("v1/rest", new WebServiceHostFactory(), typeof(BookStore)));
RouteTable.Routes.Add(new ServiceRoute("api-docs", new WebServiceHostFactory(), typeof(SwaggerWcfEndpoint)));
}
Note: Edit Web.config and add the following (if it doesn't exist yet) inside the system.serviceModel block
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
Configure WCF response auto types (optional)
We have to add the following to Web.config. This will allow the WCF service to accept requests and send replies based on the Content-Type headers.
<behavior name="webHttpBehavior">
<webHttp defaultOutgoingResponseFormat="Json" automaticFormatSelectionEnabled="true"/>
</behavior>
</endpointBehaviors>
<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="false"/>
</behavior>
Decorate WCF services interfaces
For each method, we have to configure the WebInvoke or WebGet attribute, and add a SwaggerWcfPath attribute.
[SwaggerWcfPath("Get book", "Retrieve a book from the store using its id")]
[WebGet(UriTemplate = "/books/{id}", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
Book ReadBook(string id);
Decorate WCF services class
• Add the SwaggerWcf and AspNetCompatibilityRequirements attributes to the class providing the base path for the service.
• For each method, add the SwaggerWcfTag to categorize the method and theSwaggerWcfResponse for each possible response from the service.
[SwaggerWcfTag("Books")]
[SwaggerWcfResponse(HttpStatusCode.OK, "Book found, value in the response body")]
[SwaggerWcfResponse(HttpStatusCode.NoContent, "No books", true)]
public Book[] ReadBooks()
{
}
Decorate data types used in WCF services
[DataContract]
[Description("Book with title, first publish date, author and language")]
[SwaggerWcfDefinition(ExternalDocsUrl = "http://en.wikipedia.org/wiki/Book", ExternalDocsDescription = "Description of a book")]
public class Book
{
[DataMember]
[Description("Book ID")]
public string Id { get; set; }
[DataMember]
[Description("Book Title")]
public string Title { get; set; }
[DataMember]
[Description("Book First Publish Date")]
public int FirstPublished { get; set; }
[DataMember]
[Description("Book Author")]
public Author Author { get; set; }
[DataMember]
[Description("Book Language")]
public Language Language { get; set; }
}
Reference:- https://github.com/abelsilva/swaggerwcf
That's it wcf for Swagger implemented.
Please free if you face any issue.
Thanks,
Abhi

using DTO with WCF

I have a EFM which is mapped with a POCO Entity, and m using WCF for business logic
while calling this function in the WCF :-
public List<DTO.Product> Viewall()
{
var val= _repositoryprod.GetAll().Take(2).ToList();
return val;
}
i get an error The socket connection has been disposed.
I tried serializing the DTO class and even using [DataContract] and [DataMember] attribute but no luck.
M using TCP Binding and just max every value still why its showing socket connection disposed.....
binding name="netTcpStreaming" transferMode="Streamed" maxReceivedMessageSize="4294967296" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" openTimeout="01:00:00" receiveTimeout="01:00:00" closeTimeout="01:00:00" sendTimeout="01:00:00" maxConnections="100" listenBacklog="100"
What am i doing wrong ??
The error can be caused because of the default limit for maxItemsInObjectGraph is 65536. Try changing that and retry!
Got the solution, as with EFM + POCO u need to add the ApplyDataContractResolver attribute in the WCF Operation Contracts
Just follow this walkthrough and you are done
http://msdn.microsoft.com/en-us/library/ee705457.aspx

Replacing XopDocument class in .NET 4.0

With migration to .NET 4.0, we got rid of a lot of WSE libraries, including the XopDocument class. What is the recommended class to replace XopDocument class, which represents an XOP package that is part of an MTOM-encoded SOAP message
Today I found your question when trying to understand how to add some attachment to SOAP message. In my requirements I have sample SOAP where <inc:Include href="cid:SOMEXML" xmlns:inc="http://www.w3.org/2004/08/xop/include"/> and I have to implement service which can consume such requests. I'm not experienced in WSE, so it's interesting for me for what purpose XopDocument was used there.
I resolved my issue using WCF configurations. I set messageEncoding="Mtom"
<basicHttpBinding>
<binding messageEncoding="Mtom" />
</basicHttpBinding>
and my DataContract has byte[] property.
[DataContract]
public class RootObject
{
[DataMember]
public byte[] SOMEXML { get; set; }
}
In SOAP request it looks like
<xop:Include href="cid:http%3A%2F%2Ftempuri.org%2F1%2F634654497430144369" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
In general it is what I wanted to find.

RIA services WCF timeout

I have an application which is written in silverlight 3.0. It uses RIA services to communicate between the client and server.
My question doesn't seem to be answered very well on the web. The client communicates to the server using RIA services, which uses WCF behind the scenes. If the communication takes more than 60 seconds it times out with this message,
'Load operation failed for query 'ApplyUpgrade'. The HTTP requrest to 'http://localhost:52403/ClientBin/DatabaseUpgradeTool-Web-UpgradePackageDomainService.svc/binary' has exceeded the allotted timeout. The time allotted to this operation may have been a portion of a longer timeout.'
My server is performing a database upgrade, so it is valid for it to take more than 60 seconds. Probably double or triple that.
I tried settings like this in the web.config,
<services>
<service name="DatabaseUpgradeTool.Web.UpgradePackageDomainService">
<endpoint address="" binding="wsHttpBinding" contract="DatabaseUpgradeTool.Web.UpgradePackageDomainService"></endpoint>
<endpoint address="/soap" binding="basicHttpBinding" contract="DatabaseUpgradeTool.Web.UpgradePackageDomainService"></endpoint>
<endpoint address="/binary" binding="customBinding" bindingConfiguration="BinaryHttpBinding" contract="DatabaseUpgradeTool.Web.UpgradePackageDomainService"></endpoint>
</service>
</services>
<bindings>
<customBinding>
<binding name="BinaryHttpBinding"
receiveTimeout="00:00:10"
sendTimeout="00:00:10"
openTimeout="00:00:10"
closeTimeout="00:00:10">
<binaryMessageEncoding />
<httpTransport keepAliveEnabled="true"/>
</binding>
</customBinding>
</bindings>
Still no joy. Any ideas as to what is wrong with what I have tried above? I would expect the above to cause it to timeout within 10 seconds, not 60.
Thanks.
Not sure if this will help, I haven't tried it with time outs configurations, but it might point you in the right direction:
http://blogs.objectsharp.com/CS/blogs/dan/archive/2010/04/13/maxitemsinobjectgraph-wcf-ria-services-exception.aspx
I faced the same problem, I posted the answer to this question here: Silverlight 4 WCF RIA Service Timeout Problem
Here is the answer:
I'll explain my context and I wish it will work for my. I'm sure about that.
First of all to call RIA services, and using some domain context, in my example:
EmployeeDomainContext context = new EmployeeDomainContext();
InvokeOperation<bool> invokeOperation = context.GenerateTMEAccessByEmployee(1, 'Bob');
invokeOperation.Completed += (s, x) =>
{....};
Nothing new until here. And with this I was facing every time that same timeout exception after 1 minute. I spend quite a lot of time trying to face how to change the timeout definition, I tried all possible changes in Web.config and nothing. The solution was:
Create a CustomEmployeeDomainContext, that is a partial class localizated in the same path of the generated code and this class use the hook method OnCreate to change the behavior of created domain context. In this class you should wrote:
public partial class EmployeeDomainContext : DomainContext
{
partial void OnCreated()
{
PropertyInfo channelFactoryProperty = this.DomainClient.GetType().GetProperty("ChannelFactory");
if (channelFactoryProperty == null)
{
throw new InvalidOperationException(
"There is no 'ChannelFactory' property on the DomainClient.");
}
ChannelFactory factory = (ChannelFactory)channelFactoryProperty.GetValue(this.DomainClient, null);
factory.Endpoint.Binding.SendTimeout = new TimeSpan(0, 10, 0);
}
}
I looking forward for you feedback.

Categories