DrawingsPart not being added to the WorksheetPart. Specified argument was out of the range of valid values

0

Using the Open Xml SDK, I added a DrawingsPart to a WorksheetPart and then later I tried referencing the DrawingsPart from within the WorksheetPart but I receive an ArgumentOutOfRangeException.

Here is the relevant snippet of code:

// Add a new drawings part to the worksheet
var drawingsPart = worksheetPart.AddNewPart<DrawingsPart>();

// make a drawing DOM
var drawingRootElement = new WorksheetDrawing();

// add to the drawing DOM
...

// and then...
// associate the drawing DOM to the drawings part
drawingsPart.WorksheetDrawing = drawingRootElement;

// save the drawing DOM back to the drawings part
drawingsPart.WorksheetDrawing.Save();

// and finally...
// here is where it throws the ArgumentOutOfRangeException
// whether I supply the drawingsPart as the argument
// or the value worksheet.DrawingsPart
// it reports the same exception
// I looked up the source of OpenXmlPartContainer.GetIdOfPart
// and it looks like the DrawingsPart is not yet added to the
// PartDictionary of the WorksheetPart. I wonder why?
var relationshipIdOfDrawingsPart = drawingsPart
                            .GetIdOfPart(worksheetPart.DrawingsPart /* drawingsPart */);


// Create a new drawing element and add it to the Worksheet DOM
var drawingElement = new DocumentFormat.OpenXml.Spreadsheet.Drawing { Id = relationshipIdOfDrawingsPart };
worksheetPart.Worksheet.Append(drawingElement);

Exception details:

System.ArgumentOutOfRangeException occurred HResult=0x80131502
Message=Specified argument was out of the range of valid values.
Source=DocumentFormat.OpenXml StackTrace: at DocumentFormat.OpenXml.Packaging.OpenXmlPartContainer.GetIdOfPart(OpenXmlPart part) at ... my code

I looked up the source of OpenXmlPartContainer.GetIdOfPart (reproduced below):

// DocumentFormat.OpenXml.Packaging.OpenXmlPartContainer
/// <summary>
/// Gets the relationship ID of the part.
/// </summary>
/// <param name="part">The part.</param>
/// <returns>The relationship ID of the part.</returns>
/// <exception cref="T:System.ArgumentNullException">Thrown when "part" is null reference.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the part does not exist.</exception>
public string GetIdOfPart(OpenXmlPart part)
{
    this.ThrowIfObjectDisposed();
    if (part == null)
    {
        throw new ArgumentNullException("part");
    }
    if (this.PartDictionary.ContainsValue(part))
    {
        foreach (KeyValuePair<string, OpenXmlPart> current in this.PartDictionary)
        {
            if (part == current.Value)
            {
                return current.Key;
            }
        }
    }
    throw new ArgumentOutOfRangeException("part");
}

It looks like the DrawingsPart is not being added to the PartDictionary of the WorksheetPart. I wonder why?

c#
openxml
openxml-sdk
asked on Stack Overflow Oct 12, 2017 by Water Cooler v2

1 Answer

1

Given that worksheetPart.DrawingsPart and drawingsPart are the same object, this code does not make sense:

// and finally...
// here is where it throws the ArgumentOutOfRangeException
// whether I supply the drawingsPart as the argument
// or the value worksheet.DrawingsPart
// it reports the same exception
// I looked up the source of OpenXmlPartContainer.GetIdOfPart
// and it looks like the DrawingsPart is not yet added to the
// PartDictionary of the WorksheetPart. I wonder why?
var relationshipIdOfDrawingsPart = drawingsPart
                            .GetIdOfPart(worksheetPart.DrawingsPart /* drawingsPart */);

since that would only work if the object's PartDictionary contained a reference to itself.

As such, you need to instead call GetIdOfPart on the parent object, not drawingsPart itself.

answered on Stack Overflow Oct 12, 2017 by mjwills

User contributions licensed under CC BY-SA 3.0