Reputation: 2429
After an upgrade from .NET Framework 4.8 to .NET 8 I had to change my code to somthing else because it said
entries cannot be opened multiple times in update mode.
My method gets passed a bytearray and something I want to replace my existing customxml with (the customxml part is selected by the namespace GlobalDefinitions.CustomXmlBausteinNamespace
). The result is returned properly and returns the correctly updated customxml.
My old code looked like this:
public byte[] RenewCustomXmlPart(byte[] content, string customXml)
{
using (m_log.CreateScope())
{
MemoryStream mem = CreateMemoryStream(content);
if (mem == null)
{
return null;
}
using (WordprocessingDocument mergedDocument = WordprocessingDocument.Open(mem, true))
{
foreach (CustomXmlPart item in mergedDocument.MainDocumentPart.CustomXmlParts)
{
XDocument doc = XDocument.Load(new XmlTextReader(item.GetStream()));
if (doc.Document == null)
{
throw new ArgumentNullException(nameof(doc.Document));
}
if (doc.Document.Root == null)
{
throw new ArgumentNullException(nameof(doc.Document.Root));
}
XNamespace xn = doc.Document.Root.GetDefaultNamespace();
if (xn.NamespaceName == GlobalDefinitions.CustomXmlBausteinNamespace)
{
byte[] a = Encoding.UTF8.GetBytes(customXml);
MemoryStream m = new MemoryStream(a);
item.FeedData(m);
}
}
mem.Flush();
return mem.ToArray();
}
}
}
My new code looks like this, but no matter how I write it, it never does update the byte array and just seems to return an old version with the outdate customxml.
public byte[] RenewCustomXmlPart(byte[] content, string customXml)
{
using (m_log.CreateScope())
{
using MemoryStream mem = CreateMemoryStream(content);
if (mem == null)
{
return null;
}
using WordprocessingDocument mergedDocument = WordprocessingDocument.Open(mem, true);
foreach (CustomXmlPart item in mergedDocument.MainDocumentPart.CustomXmlParts)
{
using (Stream stream = item.GetStream(FileMode.Open, FileAccess.Read))
{
XDocument doc = XDocument.Load(new XmlTextReader(stream));
if (doc.Document == null)
{
throw new ArgumentNullException(nameof(doc.Document));
}
if (doc.Document.Root == null)
{
throw new ArgumentNullException(nameof(doc.Document.Root));
}
XNamespace xn = doc.Document.Root.GetDefaultNamespace();
if (xn.NamespaceName != GlobalDefinitions.CustomXmlBausteinNamespace)
{
continue;
}
}
byte[] newCustomXmlBytes = Encoding.UTF8.GetBytes(customXml);
using MemoryStream m = new(newCustomXmlBytes);
item.FeedData(m);
}
mem.Flush();
return mem.ToArray();
}
}
Do you know what I do wrong?
Upvotes: 0
Views: 14
Reputation: 2429
After a few more hours this is my current workaround:
public byte[] RenewCustomXmlPart(byte[] documentContent, string customXml)
{
using (m_log.CreateScope())
{
using MemoryStream documentStream = CreateMemoryStream(documentContent);
if (documentStream == null)
{
return null;
}
using WordprocessingDocument mergedDocument = WordprocessingDocument.Open(documentStream, true);
foreach (CustomXmlPart item in mergedDocument.MainDocumentPart.CustomXmlParts)
{
using Stream stream = item.GetStream(FileMode.Open, FileAccess.ReadWrite);
XDocument doc = XDocument.Load(new XmlTextReader(stream));
if (doc.Document == null)
{
throw new ArgumentNullException(nameof(doc.Document));
}
if (doc.Document.Root == null)
{
throw new ArgumentNullException(nameof(doc.Document.Root));
}
XNamespace xn = doc.Document.Root.GetDefaultNamespace();
if (xn.NamespaceName != GlobalDefinitions.CustomXmlBausteinNamespace)
{
continue;
}
stream.SetLength(0);
byte[] newXmlBytes = Encoding.UTF8.GetBytes(customXml);
stream.Write(newXmlBytes, 0, newXmlBytes.Length);
break;
}
// workaround: clone the document to a new stream to have the newest changes applied
MemoryStream clonedMem = new();
mergedDocument.Clone(clonedMem);
return clonedMem.ToArray();
}
}
Upvotes: 0