none
Web Method that returns an object with properties that access the database. RRS feed

  • Question

  • PREFACE:  *** I couldn't find a way to post to the Web Service Forum, but this is more of a serialization issue I believe. If using a WCF service will resolve my issue please indicate and I will gladly migrate.  Thanks.  ***

    ----------

    We have a .NET web service that contains hundreds of web service calls.  Many of these calls return a custom object.  Many of these custom objects contain nested objects and also have properties with “getter methods” that need to access the database to return the proper value.

    The web service was initially developed using a singleton approach for database access.  There is only one database connection for all callers.  Basically the connection gets opened on first access and stays open for all subsequent web service callers to share.  It has worked adequately for years like this.

    We’d like to utilize connection pooling and have each call open a connection, perform the transaction and close the connection, returning it back to the IIS pool.  We realize that’s a better approach and have recently found a way to do this with our existing object model.   (Our existing object model uses a global static connection and when in the context of a web service, we’ve been able to put that connection object into HttpContext.Current.Items so that each call can have its own connection and all of the objects can share it without passing it around.)

    The problem is when we implemented the new technique, the last line of code in each web service call (before returning the object) closes the database connection.   Then after our last line of code executes and IIS/.NET begins to serialize our return object with all its nested objects, it must accesses the read/write properties to serialize those as well.   Some of these properties need to access the database and at this point the connection is closed and therefore we have a problem.

    Options we’ve considered:

    1. Before returning the object, call a method that populates all the properties storing a local variable so that subsequent calls to the property do not have to access the database.
      1. Probably the best way and could be done, but VERY labor intensive and I’m not sure the payoff is worth it.  Some objects also have nested collections of objects, which in turn may have more so we’d have to cascade thru all of these as well.  This literally would take weeks of coding and debugging, but may be the way we eventually go.
    2. Hooking into some later event using a SOAP extender or something similar to close the database object right before returning the XML serialized object.
      1. This seems like a good way but I’m not sure I can access HttpContext.Current.Items (where I’m storing my connection so all my objects can access it) for my specific session from a SOAP extender.
    3. Trying to serialize it myself in my code and calling Context.Response.Write(serializedObject)
      1. I’ve tried this and it blows up on nested objects and properties where it can’t find enough info to serialize some nested objects or properties that return objects.  The web service SOAP serializing code is obviously doing something I don’t know how to do.  This is also labor intensive but not as bad.
    4. Using the existing singleton connection technique to handle the serialized properties and let connection pooling work for everything else.
      1. Not ideal – I’d like to do it the right way and have a single connection per call.
    5. Re Opening and closing the connection each time a property is accessed.
      1. Could be a lot of open/closes for some calls that return a lot of nested object collections with multiple properties – even with IIS connection pooling it could be expensive.  And I’d still like 1 connection per call.

    Has anyone had this issue and if so what if anything were you able to do to resolve it?

    I’d gladly accept any recommendations.   


    • Edited by quizjax Thursday, March 31, 2016 7:40 PM
    Thursday, March 31, 2016 7:40 PM

Answers

All replies

  • The problem is when we implemented the new technique, the last line of code in each web service call (before returning the object) closes the database connection.   Then after our last line of code executes and IIS/.NET begins to serialize our return object with all its nested objects, it must accesses the read/write properties to serialize those as well.   Some of these properties need to access the database and at this point the connection is closed and therefore we have a problem.

    Yeah you have a problem, and you have to remove any code out of the public property getter/setter of any object that is serialized, because the code is going to execute when the serialized properties of the object are cast back to a concrete object and the object has behavior in the object's public property.

    You are not coming around this, and you have to remove the code out of the getter/setter. It's plain and simple.

    The object should be use auto-properties and that's it.

    And WCF is not going to resolve your issue as it uses XML serialization of objects between the WCF client and service, and you'll face the same problem.

    You should be sending simple DTO(s).

    https://en.wikipedia.org/wiki/Data_transfer_object

       

    Thursday, March 31, 2016 9:29 PM
  • I appreciate the response and I agree.  We are currently beginning to redesign the front end web site that consumes this service and as we develop that we'll do a lot of things differently in the back end (WCF) service - to include using DTOs.  I guess I was just trying to see if there was a  "quick" way to work around my issue with the existing site.  I'd like to at least quantify how connection pooling could improve response time.  Again - Thank you.
    • Edited by quizjax Friday, April 1, 2016 12:37 AM
    Friday, April 1, 2016 12:34 AM
  • You should look into using a Service Layer that consumes the WCF service, and if you are not using MVC, then you can look into using MVP.

    https://msdn.microsoft.com/en-us/library/ee658090.aspx?f=255&MSPPError=-2147217396

    Even if you don't use  MVP, you can still rip out the Service Layer code and implement it.

    https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter

    http://polymorphicpodcast.com/shows/mv-patterns/

    Friday, April 1, 2016 1:38 AM