Deserializing empty photos. Unhandled exception

Topics: Developer Forum
Jan 15, 2008 at 10:29 AM
Hi All,

I’m seeing a bug, either in Flickr, in the System.Xml.Serialization.XmlSerializer in FlickrNet, or in my understanding! My problem is with FlickrNet.Flickr.GroupPoolGetPhotos(“14093653@N00”). When I call this an unhandled exception is raised because part of the returned XML fails to parse within FlickrNet.Flickr’s XmlSerializer FlickrNet.Flickr._responseSerializer. If you call the Flickr API method in a browser:
http://api.flickr.com/services/rest/?method=flickr.groups.pools.getPhotos&apikey=e82b229e9196b5e3880304b04600905d&groupid=14093653%40N00

you’ll notice that about half way through the list of returned photos is this one:

<photo id="" owner="" secret="" server="" farm="0" title="" ispublic="" isfriend="" isfamily="" ownername="" dateadded="1199022250" />

which I’m guessing is a deleted photo. In any case the XmlSerializer fails to parse it throwing a System.InvalidOperationException "There is an error in XML document”. Interestingly, in the “troubleshooting tips” VS says
InnerException: Make sure your method arguments are in the right format.
InnerException: When converting a string to DateTime, parse the string to take the date before putting each value into the DateTime object.
I’m particularly perplexed by the second of these since FlickrNet.Photo stores its raw dates from deserialization as strings, not as DateTime objects.

You can reproduce this error fairly easily, either by writing some code to call GroupPoolGetPhotos and passing in the group ID 14093653@N00; or by running these two lines of code:

System.Xml.Serialization.XmlSerializer responseSerializer = new System.Xml.Serialization.XmlSerializer(typeof(FlickrNet.Response));
FlickrNet.Response flickrResponse = (FlickrNet.Response)responseSerializer.Deserialize(new StringReader("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<rsp stat=\"ok\">\n<photos page=\"1\" pages=\"38\" perpage=\"100\" total=\"3747\">\n\t<photo id=\"\" owner=\"\" secret=\"\" server=\"\" farm=\"0\" title=\"\" ispublic=\"\" isfriend=\"\" isfamily=\"\" ownername=\"\" dateadded=\"1199022250\" datetaken=\"\" datetakengranularity=\"\" dateupload=\"\" iconserver=\"\" iconfarm=\"0\" license=\"\" lastupdate=\"\" tags=\"\" latitude=\"0\" longitude=\"0\" accuracy=\"0\" />\n</photos>\n</rsp>\n"));

which call the deserialize with a photo collection containing just the offending photo. The string is the response my code received from the Flickr API, with the photos that parse removed.

Can anyone see why the FlickrNet.Photo XmlSerializer deserialization is falling over on empty input strings, or how I might fix it?

Cheers,

Tim.
Jan 15, 2008 at 11:58 AM
Hi All,

I can see what's the problem. The int members of FlickrNet.Photo (IsPublic, IsFriend, IsFamily, and IsPrimary) fail to deserialize from an empty string. I've fixed this in my local copy of the FlickrNet source by replacing ...

private int _isFriend;

/// <remarks/>
XmlAttribute("isfriend", Form=XmlSchemaForm.Unqualified)
public int IsFriend { get { return _isFriend; } set { _isFriend = value; } }

with ...

/// <remarks/>
XmlAttribute("isfriend", Form=XmlSchemaForm.Unqualified)
public string isfriend_raw;

/// <summary>
/// Converts the raw isfriend field to an <see cref="Int32"/>.
/// Returns -1 if the raw value was not returned.
/// </summary>
XmlIgnore
public int IsFriend
{
get
{
int returnInt;
bool parseWorked = Int32.TryParse(this.isfriend_raw, out returnInt);
if (parseWorked)
{
return returnInt;
}
else
{
return -1;
}
}
}

Cheers,

Tim.
Coordinator
Jan 15, 2008 at 12:10 PM
Edited Jan 15, 2008 at 12:12 PM
Yeah, I've seen this before. If you're going to do this though you might as well just make IsPublic a bool and have
[XmlIgnore()]
public bool IsFriend
{
  get { return isfriend_raw == "1"; }
}

What I've tried to do wherever possible is avoid have 'raw' items, mainly because these raw items have to public due to the serialization requirement. I have considered handling the serialization, but unfortunately the performance hit is not one I want to take (I have run test code, and its just not good).
Jan 15, 2008 at 1:10 PM
Thanks Sam - that's a better fix. It is a shame that thee serialized properties need to be public.
Coordinator
Jan 15, 2008 at 1:49 PM
It is indeed...