Saturday, 1 September 2012

Fixing bugs, which I introduced with the 'MoveNext' issue fixes

Last week's MoveNext() fix actually turns out to be too restrictive and yielded a subtle bug.


Symptom:


Razor Code of this format:


    @{
var image = @Model.Media("relatedMedia");
}
<<mg src="http://mce_host/forum/.../@image.UmbracoFile" alt="@image.Name" />

only returns the media path with first application launch. Subsequent calls return null. I introduced this as a bug in the last set up 'MoveNext issue' fixes.


In  ExamineBackedMedia.cs change
48:51, from,
if (media != null)
{
if (media.MoveNext())
return new ExamineBackedMedia(media.Current);
to
if (media != null)
{
media.MoveNext();
if (media.Current != null)
return new ExamineBackedMedia(media.Current);

This is because the relevant XPathNodeIterator is cached, and once the index is advanced its state is retained.


I am also going to relax the remaining restrictions involving MoveNext as follows:


Again in  ExamineBackedMedia.cs change:
64:67, from,
XPathNodeIterator xpi = xpath.Select(".");
//add the attributes e.g. id, parentId etc
if (xpi.MoveNext())
if (xpi.Current.HasAttributes)
to
XPathNodeIterator xpi = xpath.Select(".");
//add the attributes e.g. id, parentId etc
xpi.MoveNext ();
if (xpi.Current != null)
if (xpi.Current.HasAttributes)

110:113 from,
var media = umbraco.library.GetMedia(this.Id, true);
if (media != null && media.MoveNext())
{
XPathNavigator xpath = media.Current;
...
to
var media = umbraco.library.GetMedia(this.Id, true);
if (media != null)
{
media.MoveNext();
if (media.Current != null)
{
XPathNavigator xpath = media.Current;
var result = xpath.SelectChildren(XPathNodeType.Element);
while (result.MoveNext())
{
if (result.Current != null && !result.Current.HasAttributes)
{
if (string.Equals(result.Current.Name, alias))
{
string value = result.Current.Value;
if (string.IsNullOrEmpty(value))
{
value = result.Current.OuterXml;
}
Values.Add(result.Current.Name, value);
propertyExists = true;
return new PropertyResult(alias, value, Guid.Empty);
}
}
}
}
}

370:373, from,
var media = umbraco.library.GetMedia(ParentId, true);
if (media != null && media.MoveNext())
{
var children = media.Current.SelectChildren(XPathNodeType.Element);
...
to
if (media != null)
{
media.MoveNext();
if (media.Current != null)
{
var children = media.Current.SelectChildren(XPathNodeType.Element);
List mediaList = new List();
while (children != null && children.Current != null)
{
if (children.MoveNext())
{
if (children.Current.Name != "contents")
{
//make sure it's actually a node, not a property
if (!string.IsNullOrEmpty(children.Current.GetAttribute("path", "")) &&
!string.IsNullOrEmpty(children.Current.GetAttribute("id", "")) &&
!string.IsNullOrEmpty(children.Current.GetAttribute("version", "")))
{
mediaList.Add(new ExamineBackedMedia(children.Current));
}
}
}
else
{
break;
}
}
return mediaList;
}
}

DynamicXml.cs, 31:33
from,
if (xpni != null)
{
if (xpni.MoveNext())
{
var xml = xpni.Current.OuterXml;
to
if (xpni != null)
{
xpni.MoveNext();
if (xpni.Current != null)
{
var xml = xpni.Current.OuterXml;


 


Also change function GetCurrentNodeFromIterator in .../umbraco/businesslogic/xmlHelper.cs to:


		//this is very mono specific at the moment
public static XmlNode GetCurrentNodeFromIterator(XPathNodeIterator xpi)
{
if (xpi != null)
{
xpi.MoveNext();
if (xpi.Current != null)
return ((IHasXmlNode)xpi.Current).GetNode();
}

return null;
}

 

No comments:

Post a Comment

Note: only a member of this blog may post a comment.