0

I'm trying to list block attributes inside a .dwg file and save them in my database, here is the code I'm using:

using Autodesk.AutoCAD.DatabaseServices;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;

namespace CSP1257.Helpers
{
    public class AutocadHelper
    {

        public static Dictionary<string,string> ListAttributes(string dwgFile)
        {
            Dictionary<string, string> ret = new Dictionary<string, string>();

            using (Database attDb = new Database(false, true))
            {
                attDb.ReadDwgFile(dwgFile, FileShare.ReadWrite, false, null);
                Transaction tr = attDb.TransactionManager.StartTransaction();
                BlockTable bt = (BlockTable)attDb.BlockTableId.GetObject(OpenMode.ForRead);
                BlockTableRecord mBtr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);

                foreach (ObjectId msId in mBtr)
                {
                    BlockReference blkRef = (BlockReference)tr.GetObject(msId, OpenMode.ForRead);
                    AttributeCollection atts = blkRef.AttributeCollection;
                    if (atts == null)
                        continue;

                    foreach (ObjectId arId in atts)
                    {
                        AttributeReference attRef = (AttributeReference)tr.GetObject(arId, OpenMode.ForRead);
                        ret.Add(attRef.Tag, attRef.TextString);
                    }
                }
            }

            return ret;
        }
    }
}

However I'm getting this exception:

Common Language Runtime detected an invalid program.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.InvalidProgramException: Common Language Runtime detected an invalid program.

Source Error:     
Line 20:                 Transaction tr = attDb.TransactionManager.StartTransaction();

I'm not sure why I'm getting this exception though, and is there another way to achieve the same result ?

Mahmoud Aladdin
  • 1,040
  • 7
  • 9

1 Answers1

-1

Update:

The error occurs in the cast, so we need to check like something like this:

 DBObject obj = tr.GetObject(msId, OpenMode.ForRead);

                if (obj.GetType() != typeof(BlockReference)) continue;

                BlockReference blkRef = obj as BlockReference;

I think here's the problem: BlockReference blkRef = (BlockReference)tr.GetObject(msId, OpenMode.ForRead);

You are casting every object in modelspace to a block, but there could also be a line in model space. Then in the next line your trying to get the attribute collection of a line. Which is not possible.

So the solution is to check if BlkRef == null in that case just skip it.

if (BlkRef == null) continue;
Alain
  • 304
  • 3
  • 9