0

I know this question has been asked before, and many suggestions have been made, but I have tried all of them and none worked, so I am trying to see if anyone has extra knowledge on this matter.

Scenario: I have a console application in which I have added a web reference to an ASMX web service. In the console app I have generated a derived class like this:

public class OverridenWebRequestReporting : webservice.Reporting
{
    public OverridenWebRequestReporting(string addr)
        : base(addr)
    {
    }

    protected override System.Net.WebRequest GetWebRequest(Uri uri)
    {
        System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)base.GetWebRequest(uri);
        webRequest.KeepAlive = false;
        webRequest.ProtocolVersion = HttpVersion.Version10;
        webRequest.ServicePoint.ConnectionLimit = 1;
        return webRequest;
    }
}

The call to the web service method is the following:

        OverridenWebRequestReporting reportingService = new OverridenWebRequestReporting("http://some_web_location_where_the_service_is_deployed/Reporting.svc");

        CredentialCache cache = new CredentialCache();

        cache.Add(new Uri("http://some_web_location_where_the_service_is_deployed/Reporting.svc"), "NTLM",new NetworkCredential("username", "password", "domain"));

        reportingService.Credentials = cache;

        System.Net.ServicePointManager.Expect100Continue = false;

        DataTable dt = new DataTable();

        using (reportingService)
        {
            try
            {
                dt = reportingService.GetAllDocumentsMetadataFromSP("someString", "anotherString");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }

        }

Using the debugger, I can clearly see that the call is made, and it returns a valid datatable, but when the last return statement is made, the code enters the catch block, with an exception of "The underlying connection was closed: A connection that was expected to be kept alive was closed by the server." being thrown

Framework is 4.5.

Any suggestions in what else can I do to prevent the exception from being thrown?

Silviu Preda
  • 628
  • 1
  • 10
  • 31
  • Sometimes when you try adding the service as a service reference, the code generator throws the same exception, but with a detailed message. My guess is that you have something in your return value that can not be serialized to the client or you access a lazy variable that is disposed before the return is complete. – Silvermind Jun 13 '14 at 08:58
  • The console app is just a "testing environment". It's an old legacy. I could add it simply as a service reference. Do you think this might be negatively impacting the calls? – Silviu Preda Jun 13 '14 at 09:09
  • I just have an asmx that is added as a web reference. The reason (it took me a while to remember this :P) is that I cannot add a reference to System.ServiceModel to my app. – Silviu Preda Jun 13 '14 at 09:24
  • Ok, Can you tell me the return type of the value send to the client? – Silvermind Jun 13 '14 at 09:32
  • It's DataTable. Could this be a problem? Should any serialization take place? I must admit, I am not very familiar with web services. The method signature (in the service) is: `public System.Data.DataTable GetAllDocumentsMetadataFromSP(string username, string library)` – Silviu Preda Jun 13 '14 at 09:35
  • 1
    Everything send to the client must be serializable, because the client must know the rules to rebuild the data to the proper data type. I do not think a datatable is serializable. Perhaps returning the result as a concattenated string to test if no exception is thrown anymore will put you on the right track. – Silvermind Jun 13 '14 at 09:39
  • Well, this went well :) you were right about the DataTable. the string returned well, with everything in it. What would the solution be if I wanted to transport something like a datatable through to the client? A datacontract of some sort? – Silviu Preda Jun 13 '14 at 09:59
  • Yes that would be a solution, however I have very limited knowledge about asmx, I always had the luxury of a service reference. – Silvermind Jun 13 '14 at 10:13
  • 1
    `DataTable` serializes just fine. There are certain rules you have to follow though, such as setting the `TableName` property on the server side (this one has bit me the most in the past). – Kirill Shlenskiy Jun 16 '14 at 00:42

2 Answers2

1

The solution is a combination of changes:

1) Adding, as Kirill suggested, a name to the datatable

2) Using dt.WriteXml(writer, XmlWriteMode.WriteSchema, false); in the service, to generate an XML string

3) Using

using (StringReader r = new StringReader(XMLSerializedResult))
        {
            dt.ReadXml(XmlReader.Create(r));
        }

in the client to deserialize the XML string.

Thank you all for the suggestions.

Silviu Preda
  • 628
  • 1
  • 10
  • 31
0

Check out Closing WCF connection. Basically this happens when Dispose is called by the using block. Solution: skip using and call .Close or .Abort as needed.

MSDN link: http://msdn.microsoft.com/en-us/library/aa355056.aspx

Community
  • 1
  • 1
rickythefox
  • 6,601
  • 6
  • 40
  • 62
  • I have tried removing the using block (actually, it wasn't there in the beginning) but it still hits the catch block. I just added the using block hoping that this would solve the problem. It's not the case... – Silviu Preda Jun 13 '14 at 09:29