最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - CustomXML Part is not being updated with FeedData - Stack Overflow

programmeradmin2浏览0评论

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?

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?

Share Improve this question edited Mar 3 at 9:45 Jannik asked Mar 3 at 8:38 JannikJannik 2,4396 gold badges34 silver badges64 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

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();
    }
}
发布评论

评论列表(0)

  1. 暂无评论