Testing Columns in a DataSet
I ran into a nasty little surprise the other day. I was writing some code to see if a Project has a WSS site associated with it. So here is the code that I’ve cut down for brevity:
private string GetWSSSite(Guid projectGuid)
{
ProjectWS.ProjectDataSet pds =
ProjWebSvc.ReadProject(projectGuid,
ProjectWS.DataStoreEnum.PublishedStore);
ProjectWS.ProjectDataSet.ProjectRow pr = pds.Project[0];
string WSSSite = pr.WPROJ_STS_SUBWEB_NAME;
if (WSSSite.Length == 0)
return String.Empty;
else
return WSSSite;
}
Essentially I read the project, and then either pass back the subweb name or an empty string. The only problem was the routine was throwing an exception. I bet you can’t guess which line was throwing the exception…. give up? It was the assignment of the WSSSite. I was getting a System.Data.StrongTyping exception. When I started to debug and dig it thing became a little clearer. It seems I ran across a project that did not have a subweb associated with it. Since the DataSet is built directly from the database tables, the column WPROJ_STS_SUBWEB_NAME was DBNull. The DBNull brought on the StrongTyping exception. To work around this I modified the code as follows:
private string GetWSSSite(Guid projectGuid)
{
try
{
ProjectWS.ProjectDataSet pds =
ProjWebSvc.ReadProject(projectGuid,
ProjectWS.DataStoreEnum.PublishedStore);
ProjectWS.ProjectDataSet.ProjectRow pr = pds.Project[0];
return pr.WPROJ_STS_SUBWEB_NAME;
}
catch (System.Data.StrongTypingException ex)
{
return String.Empty;
}
}
So the lesson here is when testing column value be careful they may throw an exception. To get a better idea of where you may encounter problems you can go into debug mode and put a breakpoint after you fill the DataSet. If you look through the row in watch mode you will see a number of exceptions. See the attached picture for illustration.
Also note in the code above you should be testing for exceptions from the ReadProject call, but I removed that to better illustrate the column exception.
Comments
Anonymous
December 14, 2006
Isn't this what the WssInterop web service is for? You can create an instance, pass in the Project GUID into ReadWssData() and then examine the contents of that to determine whether ProjWssInfo in the DataSet you got back was populated. No?Anonymous
December 14, 2006
This sample was part of something much larger I was working on. This is meant to illustrate being careful of return data in the datasets, not functional aspects of interacting with WSS.Anonymous
December 14, 2006
Not wanting to argue, but as someone who has witnessed lots of code from blogs in production systems as developers cut 'n' paste from the web I like to see best-practice being preached wherever possible. So would it not be better to test your values using the supplied PSI methods for doing so? Such as: http://msdn2.microsoft.com/en-us/library/websvcproject.projectdataset.projectrow.iswproj_sts_subweb_namenull.aspx Would that pick up on the DBNull and correctly return true, or would you still receive the StrongTypingException?Anonymous
January 08, 2007
Larry Duff of the Project team wrote a very nice article describing how to test column values when makingAnonymous
May 17, 2007
How we can retrived GUID of all Sites. We are trying to use WssInterop.ReadWssServerInfo, but it is not properly working. If any one has the idea, please let me know