8

I am making this call in my WCF service:

public User GetStudentRecord(string userName)
    {
        try
        {
            return new DashboardFacade().GetStudentRecord(userName);
        }
        catch (Exception ex)
        {
            ServiceFault fault = new ServiceFault();
            fault.Operation = "GetStudentRecord";
            fault.Reason = "Who knows...";
            fault.Message = ex.Message;
            throw new FaultException<ServiceFault>(fault, fault.Message, new FaultCode(fault.Reason), fault.Operation);
        }
    }

DashboardFacade().GetStudentRecord(..) is defined like this:

public User GetStudentRecord(string userName)
{
    User user = ctx.Users.Where(x => x.ADUserName == userName).SingleOrDefault();
    return user;
}

ctx is my DbContext. I am using Entity Framework Code First. The User object looks like this:

public class User
{
    public User()
    {
        //UserDetails = new UserDetail();
    }
    [Key]
    public Guid MasterKey { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string ADUserName { get; set; }
    public string UserType { get; set; }
    public virtual UserDetail UserDetails { get; set; }
    public Nullable<DateTime> LastModifiedDate { get; set; }
}

And finally, you probably need to see the web.config on the WCF Application:

<?xml version="1.0"?>
    <configuration>
      <connectionStrings>
        <add name="NotMyDBContextDB" connectionString="[omitted]" providerName="System.Data.SqlClient"/>
        <add name="ApplicationContext" connectionString="Data Source=.;Initial Catalog=MyApp;Integrated Security=True;Pooling=False" providerName="System.Data.SqlClient"/>
      </connectionStrings>
   <system.web>
     <compilation debug="true" targetFramework="4.0"/>
   </system.web>
   <system.serviceModel>
     <behaviors>
       <serviceBehaviors>
          <behavior>
             <serviceMetadata httpGetEnabled="true"/>
             <serviceDebug includeExceptionDetailInFaults="true"/>
          </behavior>
        </serviceBehaviors>
      </behaviors>
      <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
  </system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>

Can anyone point me to where I am going wrong here?

This is the exact error I am getting:

An error occurred while receiving the HTTP response to http://localhost:5843/MyService.svc. 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.

Inner Exception:
The underlying connection was closed: An unexpected error occurred on a receive.

Inner Exception:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

Inner Exception:
An existing connection was forcibly closed by the remote host
E_net4
  • 27,810
  • 13
  • 101
  • 139
ledgeJumper
  • 3,560
  • 14
  • 45
  • 92
  • Where is the error being thrown? Run your service in the debugger. – dthorpe Apr 04 '13 at 21:21
  • Just added the error and inner exception messages I am getting. I can run it in the debugger and it lets me step through all of the code I have above. Once I leave GetStudentRecord() call in the actual service I get the error a few seconds later. – ledgeJumper Apr 04 '13 at 21:30

7 Answers7

11

Found the root cause after a lot of swearing and thinking of how nice the weather is outside. I remove the virtual keyword from the UserDetails object that is inside the User object.

Now it works!

As far as why this caused an issue, my assumptions are serialization or DbContext issues, but I will have to look more into it, not sure.

I'm going outside now.

So for reference, if you wound up here and have no idea what is going on, among all the other things you should look at (size, timeout, etc):

Check to see if your object has virtual keyword on it.
ledgeJumper
  • 3,560
  • 14
  • 45
  • 92
8

I had this problem and in my case, the issue was the WCF service was returning a class that had a property with only a getter and no setter. I was trying to prevent the property from being modified by the receiver. To get around this, see this...

WCF Services and Object Constructors

Community
  • 1
  • 1
TheLogicMan
  • 371
  • 4
  • 12
  • That saved me! The actual error was caused by a read only property which had was throwing a null reference exception... But this was all hidden deep down. WCF madness! – Schalk Apr 16 '15 at 05:28
  • Just came here to post this. Wish I had seen this sooner. The `DataContractSerializer` requires properties to have a setter (though it may accept any access modifier on that setter) even when only serializing, not deserializing, which to me makes no sense. That apparently blows up the response at a point where it reacts by forcibly closing the connection giving you this unhelpful error message. In my case my properties were calculated based on other properties and I just wanted to return those calculated values to the client. – xr280xr Apr 09 '20 at 01:12
  • An aside: Visual Studio (and I'm guessing svcutil) will still create a getter and a setter for the property regardless of whether you declare a setter. Needing to control how a client can use the data returned from your service might be an indication of a larger design flaw. Even if you could prevent setting it, the client can copy all the values into its own local type and modify whatever it wants there. Your service can control what it accepts so if you received a value that shouldn't have been set, you could simply ignore it, return a validation error, or not receive it in the first place. – xr280xr Apr 09 '20 at 01:14
3

I had the same error.

In my case I have a table with an int column called OEM. In the model layer I have a class (DTO) with that column represented by an Enum. There was a row in the table which value in OEM colum was not valid. When I was trying to bring all data using LINQ, there was an error that wasn't captured by VisualStudio. That error raised when WCF tried to retrieve the message.

Carolina
  • 31
  • 1
  • For me it was that my enum doesn't had an explicit value for `0` defined and I passed a object via WCF which had a property of this enum type but the property wasn't assigned (which defaults to `0`). – croxy Jul 23 '19 at 09:14
1

I had the same Exception but none of the answers above gave me a solution. I figured out the error by defining a trace in web.config :

<system.diagnostics>
<sources>
  <source propagateActivity="true" name="System.ServiceModel" switchValue="Information, ActivityTracing">
    <listeners>
      <add type="System.Diagnostics.DefaultTraceListener" name="Default">
        <filter type="" />
      </add>
      <add initializeData="C:/temp/tracelog.svclog" type="System.Diagnostics.XmlWriterTraceListener" name="traceListener">
        <filter type="" />
      </add>
    </listeners>
  </source>
</sources>
</system.diagnostics>

I ran the website locally, fired a few failing calls and the opened the tracelog selecting the failed entry, inside that entry I saw this exception :

The entity or complex type 'Person' cannot be constructed in a LINQ to Entities query.

Constructing the person outside of the query fixed the issue so instead of :

 var persons = (from p in db.Persons
                  select new Person
                  {
                      Id = p.Id,
                      Name = p.Name,
                      LastName = p.LastName,
                      Email = p.Email
                  }
              ).AsEnumerable();

  return persons;

I had to do :

var persons = (from p in db.Persons
                  select new 
                  {
                      Id = p.Id,
                      Name = p.Name,
                      LastName = p.LastName,
                      Email = p.Email
                  }
              ).AsEnumerable()
                //construct the complex type outside of DB  (to prevent the exception that model cannot be constructed in linq to entities)
                .Select(item =>

                    new Person
                    {
                        Id = item.Id,
                        Name = item.Name,
                        LastName = item.LastName,
                        Email = item.Email
                    }).ToList(); 

            return persons;

I could have saved alot of time if the exception message was more comprehensive, judging by all the different causes outlined in this topic I guess people will agree with me.

Anyway, this is how I figured out the issue, hopefully this will help someone else to

Tim Bijnens
  • 310
  • 2
  • 11
0

None of the methods worked for me. What I did was to debug the service while running from the WCF Test Client and I was able to find my issue. It was to do with the service library missing the connection string in the app.config.

Just posting if anyone has tried all the other methods and still unable to find the issue.

Priyan Perera
  • 560
  • 1
  • 7
  • 20
0

Maybe you need to disable lazyloading and proxycreation, like this:

  db.LazyLoadingEnabled = false;
  db.ProxyCreationEnabled = false;

Doing this your wcf service should work.

Xtremexploit
  • 319
  • 4
  • 7
0

I had a worse case with the Webservice.

I returned a simple POCO object with an Enum property.

The numeric value returned in the property was not in the set of Enum values, and because of that, I got that misleading error.

This is not the 1st time I had an issue related to an Enum value in .NET ....

So in short, make sure your response in your WebService doesn't do this:

enum exampleEnum
    {
        A = 1
    }

    class webService
    {
        public object foo() // Suppose WebService method
        {
            // Bad, make sure the Enum value is in the list defined!
            return new { age = 12, A = (exampleEnum)2 };
        }
    }
OZ_CM
  • 61
  • 1
  • 6