Программное назначение названия сети с символом вертикальной черты

Автор Тема: Программное назначение названия сети с символом вертикальной черты  (Прочитано 4428 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Всем привет!
Сегодня поймал новую неприятную "особенность" Civil 3D API. Присутствует в Civil 3D 2019, в других пока не проверял. Вкратце, проблема такая: вручную, через пользовательский интерфейс в имени сети можно использовать вертикальную черту (символ |), а программно такое имя сети не задать!

Код тестовой команды:
Код - C# [Выбрать]
  1. using System.Linq;
  2. using Autodesk.AutoCAD.ApplicationServices.Core;
  3. using Autodesk.AutoCAD.DatabaseServices;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.Civil.ApplicationServices;
  6. using Autodesk.Civil.DatabaseServices;
  7.  
  8. namespace CivilTest
  9. {
  10.     public class TestNetworkNaming
  11.     {
  12.         [CommandMethod(nameof(SetNetworkNameTest))]
  13.         public void SetNetworkNameTest()
  14.         {
  15.             var civilDocument = CivilApplication.ActiveDocument;
  16.             var networkId = civilDocument.GetPipeNetworkIds().Cast<ObjectId>().FirstOrDefault();
  17.             if (networkId.IsValid)
  18.             {
  19.                 SetNetworkName(networkId, "Test|Network");
  20.             }
  21.         }
  22.  
  23.         /// <summary>
  24.         /// Присвоение названия сети
  25.         /// </summary>
  26.         /// <param name="networkId">ObjectId сети</param>
  27.         /// <param name="name">Название</param>
  28.         public static void SetNetworkName(ObjectId networkId, string name)
  29.         {
  30.             var database = networkId.Database;
  31.             var document = Application.DocumentManager.GetDocument(database);
  32.             using (document.LockDocument())
  33.             using (var transaction = database.TransactionManager.StartTransaction())
  34.             {
  35.                 var network = transaction.GetObject(networkId, OpenMode.ForWrite, false, true) as Network;
  36.                 if (network != null)
  37.                 {
  38.                     try
  39.                     {
  40.                         network.Name = name;
  41.                     }
  42.                     catch (System.Exception e)
  43.                     {
  44.                         document.Editor.WriteMessage("\nException: {0}", e.Message);
  45.                     }
  46.                 }
  47.  
  48.                 transaction.Commit();
  49.             }
  50.         }
  51.     }
  52. }
  53.  

Результат её работы:
Exception: Error: string contents for attribute 'Test|Network' contain invalid characters.  The following characters are not valid in object names: <>/\":;=|,*?`
Видеозапись проверки с голосовыми комментариями (прошу прощения за тихий звук):


Может у кого-то есть идеи, как это попробовать обойти?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Вкратце, проблема такая: вручную, через пользовательский интерфейс в имени сети можно использовать вертикальную черту (символ |), а программно такое имя сети не задать!
Честно говоря очень странно, что такое имя можно задать через пользовательский интерфейс, так как в AutoCAD есть особое назначение для этого символа - использование в именах из внешних ссылок. Скорее всего это победить нельзя. Но можно задать этот вопрос в ADN DevHelp.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Про ограничения метода Name класса Network ничего не сказано в документации, зато есть в описании метода Create:
http://docs.autodesk.com/CIV3D/2019/ENU/API_Reference_Guide/html/45fec93e-f4c7-e5fc-6112-0ce7d676cfe2.htm
Интересно, что там перечислены недопустимые символы, но "|" среди них не упоминается.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Да, при создании сети проверяются другие символы:
Код - C# [Выбрать]
  1. namespace Autodesk.Civil.DatabaseServices
  2. {
  3.   [Wrapper("AeccDbNetwork")]
  4.   public sealed class Network : GeoEntity
  5.   {
  6.     public static unsafe ObjectId Create(CivilDocument document, ref string networkName)
  7.     {
  8.       string str1 = networkName;
  9.       if (null == (object) str1)
  10.         throw new ArgumentNullException();
  11.       if (str1.Trim().Length == 0)
  12.         throw new ArgumentException("Key can't be blank.");
  13.       string str2 = "\\\",/;?*=:";
  14.       if (networkName.IndexOfAny(str2.ToCharArray()) != -1)
  15.         throw new ArgumentException("The invalid characters in Key are: '\\', '\"', ',', '/', ';', '?', '*', '=', ':'");
  16. ...
  17.  
Я так подозреваю, что в API не стали переопределять базовый метод задания имени объекту Civil, в котором больше ограничений.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Я так подозреваю, что в API не стали переопределять базовый метод задания имени объекту Civil, в котором больше ограничений.
100%
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Дмитрий Загорулькин 12-10-2020, 15:26:46

Оффлайн Дмитрий ЗагорулькинАвтор темы

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Снова COM выручает  :)
Так работает:
Код - C# [Выбрать]
  1. /// <summary>
  2. /// Присвоение названия сети
  3. /// </summary>
  4. /// <param name="networkId">ObjectId сети</param>
  5. /// <param name="name">Название</param>
  6. public static void SetNetworkName(ObjectId networkId, string name)
  7. {
  8.     var database = networkId.Database;
  9.     var document = Application.DocumentManager.GetDocument(database);
  10.  
  11.     dynamic netCom = null;
  12.  
  13.     using (document.LockDocument())
  14.     using (var transaction = database.TransactionManager.StartTransaction())
  15.     {
  16.         var network = transaction.GetObject(networkId, OpenMode.ForRead, false, true) as Network;
  17.         if (network != null)
  18.         {
  19.             netCom = network.AcadObject;
  20.         }
  21.  
  22.         transaction.Commit();
  23.     }
  24.  
  25.     if (netCom == null)
  26.     {
  27.         return;
  28.     }
  29.  
  30.     try
  31.     {
  32.         netCom.Name = name;
  33.     }
  34.     catch (System.Exception e)
  35.     {
  36.         document.Editor.WriteMessage("\nException: {0}", e.Message);
  37.     }
  38. }
  39.  

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение