This blog has moved!

Check out www.CodeBetter.com/blogs/grant.killian

<July 2008>
SuMoTuWeThFrSa
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789


Navigation

Professional Props...

Extracurricular Props...

Subscriptions

Article Categories



Wednesday, June 16, 2004 - Posts

Web Service gotcha: DataSet.HasErrors HasProblems

I've spent the last few hours wrestling with the issue identified in Microsoft KB Article 818587; in a nutshell, serialized DataSet objects that have Row or Column Errors can have trouble when passed between web services to client consumers.  My specific case is an Excel-based data editor (using VSTO) that relies on Web Services for transmitting data to and from the data server. 

Everything was going great until I started expanding the proof-of-concept to handle concurrency exceptions -- I'm dutifully using a SqlRowUpdatedEventHandler to manage concurrency errors and after I kept getting NullReferenceExceptions after passing the DataSet with the Errors back to the client, I discovered KB Article 818587.  At this point I scratched my head some and thought this through: this isn't your typical KB Resolution from Microsoft, it says “To resolve this problem, contact Microsoft Product Support Services to obtain the fix.“  It goes on to indicate the resolution is to install a new System.Data assembly, which sounds innocent on it's own, but this will throw the configuration management folks here (and more importantly, at the client) into fits. 

A thought occurred to me: since it's 1) late in the evening and I don't feel up to a Microsoft call and 2) pretty certain our customer will not like having to run a special “patched“ System.Data dll just for this app, why don't I try to program my way out of this paper bag?

I decided to circumvent the native Web Service serialization and try my own, to see if I could get my DataSet to successfully transfer between server and client without the magic dll from Microsoft.  I created a Serialization Helper class to convert any object into a serialized string (note: I used the very verbose SoapFormatter instead of the BinaryFormatter to ensure that my string transfers without loss of data -- yes it's slower but in this case it's a necessary evil):

  public static string getSerializedVersion( object obj )
  {
   System.Runtime.Serialization.Formatters.Soap.SoapFormatter soap =
    new System.Runtime.Serialization.Formatters.Soap.SoapFormatter() ;
   byte[] buf ;
   System.IO.MemoryStream mem = new System.IO.MemoryStream() ;
   soap.Serialize( mem, obj ) ;
   buf = mem.ToArray() ;
   return System.Text.UTF8Encoding.UTF8.GetString( buf ) ;
  }
 

You may think: isn't this what the SOAP plumbing for Web Services does already?  Conceptually, I think that's true, but there's obviously some magic in my manual serialization of the object since it succeeds where the intrinsic Web Service serialization fails with the nasty NullRef XML exception.  This may be a bit slower, but I'll take slower code that runs over fast code that doesn't really work any day!  By the way, for this to work you'll need to reference System.Runtime.Serialization.Formatters.Soap.dll in your project.

To use this SerializationHelper class, we can just do the following to return a string from our web method:

    theDataAdapter.Update( theDataSet ) ;
    return SerializationHelper.getSerializedVersion( theDataSet ) ;

The flip side to this is that the client has to specially deserialize our DataSet; we can use a SerializationHelper class to do something like the following (this time I'll show VB.Net since our client using Excel is written in VB.Net, sorry C# purists, see this post for why!):

 dim strResult as string = objWebSvc.getDataSetWithPotentialErrors()
 dim soap as New System.Runtime.Serialization.Formatters.Soap.SoapFormatter()
 dim buf as byte() = System.Text.UTF8Encoding.UTF8.GetBytes( strResult )
 dim mem as IO.MemoryStream = new IO.MemoryStream( buf )
 dim obj as Object = soap.Deserialize( mem )
 theDataSet = CType( obj, DataSet )

OK, so where does this get me?  I've managed to avoid calling Microsoft and aggravating our customer with a special System.Data assembly requirement for the project; I think I've programmed myself out of the paper bag in time to watch the Daily Show on Comedy Central! 

I'm sure somebody from my company will contact Microsoft about the KB Resolution and our work-around, to see what the whole story is.  If it's worthwhile, I'll post a follow up.  Until then, I'm content with this approach.  I've spent some time in the various newsgroups and I'm not the only one who wrestled with this known issue, perhaps this will prevent you from spinning your wheels too long on it.

Happy .Netting!

posted Wednesday, June 16, 2004 8:07 PM by grant.killian

My latest little tactic (no Web Service dust involved) . . .

. . . has been to take advantage of the Debug conditional compilation constants and Trace and Assert to my heart's content.  It also lets me circumvent some time consuming authentication code or pre-fill forms with test values, etc.  It can be as simple as the following in the global.asax Session_Start() event handler:

#if( DEBUG )
    Session.Contents[ "Authenticated" ] = "true" ;
#else
   //no special action
#endif

When you do a Debug build, the DEBUG constant evaluates to true; if you do a Release build -- shocker -- the Debug constant is false.  It's all handled automatically by Visual Studio .Net from the Project Properties->Build->Code Generation section (by default TRACE is another constant defined for Debug AND Release builds).

I know this isn't a glitzy new feature with XML baked in and Web Service dust sprinkled on it, but it is a nice little measure to remember!  By the way, my above example using a Session variable is very bug prone . . . for production code I make a typed session manager like Mark does here.

Happy .Netting!

posted Wednesday, June 16, 2004 10:10 AM by grant.killian

MSDN Magazine Overload

I was interested to see the edge of a shrink-wrapped magazine in my mailbox at work this morning . . . until I pulled out the magazine and realized it was another copy of MSDN's July issue.  This is the 3rd copy of this that I've gotten in the mail, and while I'm happy to have the information, I don't really need three printed copies of it all.  This has been happening for a number of months, so this isn't just an anomalous month!  

I realize that through conference registrations for DevScovery and TechEd, and the role I play in the WeProgram.Net user group, I'm privy to a complementary subscription for a year or so . . . but I didn't think MSDN Magazine would just ship duplicate magazine issues my way each month.  And then duplicates of the duplicates!  I'm betting I'm not the only one in this situation. 

I've been giving the magazine to coworkers and our user group has an ample number of people who like to take the free magazine, so I'm not complaining so much as observing that MSDN Magazine is not in the business of making money so much as they are in spreading the gospel according to Microsoft development.  I have it on good authority that MS Press is not a lucrative publishing effort, and I suppose MSDN Magazine falls under the same umbrella (although sponsor ads probably generate some nice revenue for the magazine).  Microsoft likes having the channel to the developer community that MSDN Mag provides and I don't blame them for it; this explains why we see posts like this one questioning the content choices of the magazine . . . MSDN magazine is going to generally be “on message” and in sync with the Microsoft public direction. 

So, the moral of the story is twofold:

  1. Don't take a gift MSDN Magazine issue for granted (there's usually good content in there and if you get duplicates, they make good -- albeit small -- user group giveaways).
  2. Recognize the source of the “journalism“ in MSDN and take it with a grain of salt.  I've learned lots of interesting things from reading MSDN, but I've also skipped over articles on things like Web Classes (anybody remember those?) and close MS Passport integration.  Take it with a grain of salt!

Happy .Netting!

posted Wednesday, June 16, 2004 9:19 AM by grant.killian




Powered by Dot Net Junkies, by Telligent Systems