title: OpenXml image relationship doesn't exist
body: <p>I'm an intern at a large company who got tasked with working on a previous intern's project that apparently worked at some point, but now it's broken. What the program does, is it takes a bunch of text and images out of a document and inserts them into a template document. The problem is, about half of the images aren't forming relationships and I'm getting the red X "Image cannot be displayed" empty box. I've been doing some digging with the productivity tool, and I found out that there are a couple duplicate IDs, as well as quite a few non-existent relationships, although looking at his code I'm not sure what might be causing that. Here are his 2 methods for copying images:</p>
  
  <pre><code>internal static void CopyImages(OpenXmlElement oldTable, OpenXmlElement newTable,
          WordprocessingDocument testData, WordprocessingDocument testReport)
      {
          List&lt;Blip&gt; sourceBlips = DocumentHelper.GetAllBlips(oldTable);
          List&lt;Blip&gt; targetBlips = DocumentHelper.GetAllBlips(newTable);
  
          foreach (Blip sourceBlip in sourceBlips)
          {
              foreach (Blip targetBlip in targetBlips)
              {
                  if (targetBlip.Embed.Value == sourceBlip.Embed.Value)
                  {
                      if (testData.MainDocumentPart.GetPartById(sourceBlip.Embed.Value) is ImagePart imagePart)
                      {
                          ImagePart newImagePart = testReport.MainDocumentPart.AddPart(imagePart);
  
                          targetBlip.Embed.Value = testReport.MainDocumentPart.GetIdOfPart(newImagePart);
                          break;
                      }
                  }
              }
          }
      }
  
      internal static void CopyEmbeddedVisioImages(OpenXmlElement oldTable, OpenXmlElement newTable,
          WordprocessingDocument testData, WordprocessingDocument testReport)
      {
          List&lt;EmbeddedObject&gt; sourceObjects = oldTable.Descendants&lt;EmbeddedObject&gt;().ToList();
          List&lt;EmbeddedObject&gt; targetObjects = newTable.Descendants&lt;EmbeddedObject&gt;().ToList();
  
          foreach (EmbeddedObject targetobj in targetObjects)
          {
              foreach (EmbeddedObject sourceObj in sourceObjects)
              {
                  if (testData.MainDocumentPart.GetPartById(sourceObj.Descendants&lt;ImageData&gt;()
                                  .FirstOrDefault().RelationshipId) is ImagePart oldImagePart)
                  {
                      ImagePart newImagePart = testReport.MainDocumentPart.AddPart(oldImagePart);
  
                      targetobj.Descendants&lt;ImageData&gt;().FirstOrDefault().RelationshipId =
                      testReport.MainDocumentPart.GetIdOfPart(newImagePart);
                  }
  
  
                  if (testData.MainDocumentPart.GetPartById(sourceObj.Descendants&lt;OleObject&gt;()
                                  .FirstOrDefault().Id) is OpenXmlPart openXmlPart)
                  {
                      EmbeddedObjectPart newEmbeddedObj = (EmbeddedObjectPart)testReport.MainDocumentPart.AddPart(openXmlPart);
  
                      targetobj.Descendants&lt;OleObject&gt;().FirstOrDefault().Id =
                                  testReport.MainDocumentPart.GetIdOfPart(newEmbeddedObj);
                  }
              }
          }
      }
  </code></pre>
  
  <p>I've tried calling Save() and Close() on the documents. I even tried calling Dispose(). <code>using(WordprocessingDocument foo = WordprocessingDocument.Open(bar, false){}</code> doesn't seem to help either. I'm not too worried about the duplicate IDs for now, but I have no idea why only some of the relationships are being formed while others are not. This is a massive project so navigating through some of it can be pretty tricky.</p>
  
  <p>Edit: It's probably also worth mentioning that the images stop forming relationships at a certain point. It isn't random. About 2/3 of the way down none of the images work.</p>
  
  <p>Here's the updated set of methods</p>
  
  <pre><code>internal static void CopyImages(OpenXmlElement oldTable, OpenXmlElement newTable,
          WordprocessingDocument testData, WordprocessingDocument testReport)
      {
          List&lt;Blip&gt; sourceBlips = DocumentHelper.GetAllBlips(oldTable);
          List&lt;Blip&gt; targetBlips = DocumentHelper.GetAllBlips(newTable);
  
          foreach (Blip sourceBlip in sourceBlips)
          {
              foreach (Blip targetBlip in targetBlips)
              {
                  if (targetBlip.Embed.Value == sourceBlip.Embed.Value)
                  {
                      if (testData.MainDocumentPart.GetPartById(sourceBlip.Embed.Value) is ImagePart imagePart)
                      {
                          //ImagePart newImagePart = testReport.MainDocumentPart.AddPart(imagePart);
                          ImagePart newImagePart = testReport.MainDocumentPart.AddImagePart(imagePart.ContentType);
                          newImagePart.FeedData(imagePart.GetStream(FileMode.Open, FileAccess.Read));
                          targetBlip.Embed.Value = testReport.MainDocumentPart.GetIdOfPart(newImagePart);
                          break;
                      }
                  }
              }
          }
      }
  
      internal static void CopyEmbeddedVisioImages(OpenXmlElement oldTable, OpenXmlElement newTable,
          WordprocessingDocument testData, WordprocessingDocument testReport)
      {
          List&lt;EmbeddedObject&gt; sourceObjects = oldTable.Descendants&lt;EmbeddedObject&gt;().ToList();
          List&lt;EmbeddedObject&gt; targetObjects = newTable.Descendants&lt;EmbeddedObject&gt;().ToList();
  
          foreach (EmbeddedObject targetobj in targetObjects)
          {
              foreach (EmbeddedObject sourceObj in sourceObjects)
              {
                  if (testData.MainDocumentPart.GetPartById(sourceObj.Descendants&lt;ImageData&gt;()
                                  .FirstOrDefault().RelationshipId) is ImagePart oldImagePart)
                  {
                      //ImagePart newImagePart = testReport.MainDocumentPart.AddPart(oldImagePart);
                      ImagePart newImagePart = testReport.MainDocumentPart.AddImagePart(oldImagePart.ContentType);
                      newImagePart.FeedData(oldImagePart.GetStream(FileMode.Open, FileAccess.Read));
  
                      targetobj.Descendants&lt;ImageData&gt;().FirstOrDefault().RelationshipId =
                      testReport.MainDocumentPart.GetIdOfPart(newImagePart);
                  }
  
  
                  if (testData.MainDocumentPart.GetPartById(sourceObj.Descendants&lt;OleObject&gt;()
                                  .FirstOrDefault().Id) is OpenXmlPart openXmlPart)
                  {
                      EmbeddedObjectPart newEmbeddedObj = (EmbeddedObjectPart)testReport.MainDocumentPart.AddPart(openXmlPart);
  
                      targetobj.Descendants&lt;OleObject&gt;().FirstOrDefault().Id =
                                  testReport.MainDocumentPart.GetIdOfPart(newEmbeddedObj);
                  }
              }
          }
      }
  </code></pre>
  
  <p>Here's an update on my findings. </p>
  
  <ul>
  <li>There are 25 total blips in the entire document.</li>
  <li><code>targetBlip.Embed.Value != sourceBlip.Embed.Value</code> in most cases or maybe it's something else?</li>
  <li>Elements containing pictures are cloned from source doc and then saved into target doc.</li>
  <li>All elements are being read. Tables containing pictures with broken relationships exist and are filled with other content, so it's not like it's missing those elements.</li>
  <li>The duplicate IDs are due to the target document containing a couple images to begin with, so when I copy over the other images, some of those IDs are duplicated. This isn't my concern for now.</li>
  </ul>