TagElement.GetTagValue() is not returning the values presented in Microstation, what might be wrong? C#

Hello,

I have encountered something I find quite odd.

In an application I have written I've used the function GetTagValue() in order to retrieve the value of a TagElement.

I have tested this on a few different files and I have gotten the expected result in all but one. Instead of getting the assigned values I'm getting an empty string for 99% of the tags in that one file, the other 1% of the tags works as expected.

Looking at the tags in Microstation I have concluded that 80% of the tags should return something other than an empty string.

Any idea what might be causing this?

Using Microstation 10.16.03.11

// using Bentley.DgnPlatformNET;

// This is the exact row I'm using.
var tagValue = tag.GetTagValue().ToString();

Parents
  • Hi Petter,

    Any idea what might be causing this?

    It's hard to guess without knowing the data.

    I would assume the file is corrupted (because tags are not very robust), plus maybe a minor bug in API (tags or obsolete in CE, so my experience is that they are on a "minor level" in terms of focus and importance.

    Two questions:

    • What is returned by GetTagValue() method? You wrote ToString() returns empty string, which does not tell nothing else about the returned object that it has "empty string default representation".
    • Can be these tags reviewed and/or edited by MicroStation CE tools?

    With regards,

      Jan

  • Hello Jan,

    Regarding question one. The output from tag.GetTagValue is empty string as object.

    Question two, yes I can edit the tags using the MS CE tools.

    A conversion to Item Types is possible but not really suitable in my current scenario unfortunately.

    Of course, Item Types provide a better alternative, more suitable for the 21st century.

    Definitely agree.

  • The output from tag.GetTagValue is empty string as object.

    I disagree, because what is returned is "object" with no defined type.

    What Visual Studio shows is a result of ToString() method, available for all objects in NET Framework. But it does not tell anything about the object itself, it only returns, what the particular object returns in this method.

    Unfortunately in NET, the returned object is general object, but native API works with DgnTagValue class. I checked how NET wrapper is implemented and it is based on DgnTagValue class too, but it is not available publicly (is casted internally to a general object before returned from the method).

    It's not easy to understand decompiled IL code, but code page and string allocations are used there, so maybe the problem is that tags (on 8bit based V8 platform) were filled with some specific unusual code page set, so string transformation failed and empty string is returned?

    With regards,

      Jan

  • Thanks for the input Jan,

    I disagree, because what is returned is "object" with no defined type.

    True.

    so maybe the problem is that tags (on 8bit based V8 platform) were filled with some specific unusual code page set

    It might be but I think it's unlikely, however I'm a bit unfamiliar regarding encoding in Microstation. Wouldn't that result in strange values when I view them in Microstation? Is the code page determined by configuration of Microstation or does the DgnFile define what code page to use?

  • It might be but I think it's unlikely

    I agree, but unfortunately nobody knows when something tiny is corrupted in DGN file.

    however I'm a bit unfamiliar regarding encoding in Microstation

    It is not simple topic, because different solutions were used historically, plus MicroStation maintains compatibility even with old 8bit and DGN V7 era. Very good intro for programmers is this blog (it was important on V8 platform).

    Is the code page determined by configuration of Microstation or does the DgnFile define what code page to use?

    See the blog, because both options - and even more - are valid (although it is not DgnFile, but "per element" encoding information internally).

    But I think it is not crucial for the issue solution, because when it is possible to edit tags in MicroStation, at least native API is able to handle the tags correctly (even when probably not correct).

    In my opinion several solutions exist, but no from them is simple one. It would be interesting to debug NET API to check why empty value is returned: If tag element is correct and casting to returned object does not work, or the problem is in the tag element itself. Such debug requires some tool, allowing to debug 3rd party assemblies.

    Another test can be to use C++ method (or even old mdlTag... function), because native API probably works fine.

    Solutions?

    • To use P/Invoke to call mdlTag function to obtain the tag value. Must be tested whether it is possible technically, but the function exists.
    • To use C++/CLI to write own wrapper. It requires to know C++/CLI and makes project more complex, so to solve this one issue only is such use probably an overkill.
    • To use ECQuery to obtain tag values through "data transformation to EC format". Personally I prefer this way, but it requires to know how tags are transformed to EC data and how to traverse EC data when linked through relationship classes.
    • To use old (classic) Interop to access tags. Probably simple, but must be tested f it works (I think to write VBA macro should be enough).

    With regards,

      Jan

  • Thanks for the suggestions Jan,

    Ended up using the fourth suggestion and it worked as expected. What a relief!

    See the code below for solution.

    // using uStnDgn = Bentley.Interop.MicroStationDGN;
    // using uStn = Bentley.MstnPlatformNET.InteropServices.Utilities;
    
    // The variable "tag" is a Bentley.DgnPlatformNET.Elements.TagElement
    
    uStnDgn.TagElement interopTag = uStn.ComApp.ActiveModelReference.GetElementByID(tag.ElementId) as uStnDgn.TagElement;
    
    if (interopTag == null)
    {
        continue;
    }
    
    var tagValue = interopTag.Value.ToString();

    Answer Verified By: Petter Vennberg 

Reply
  • Thanks for the suggestions Jan,

    Ended up using the fourth suggestion and it worked as expected. What a relief!

    See the code below for solution.

    // using uStnDgn = Bentley.Interop.MicroStationDGN;
    // using uStn = Bentley.MstnPlatformNET.InteropServices.Utilities;
    
    // The variable "tag" is a Bentley.DgnPlatformNET.Elements.TagElement
    
    uStnDgn.TagElement interopTag = uStn.ComApp.ActiveModelReference.GetElementByID(tag.ElementId) as uStnDgn.TagElement;
    
    if (interopTag == null)
    {
        continue;
    }
    
    var tagValue = interopTag.Value.ToString();

    Answer Verified By: Petter Vennberg 

Children
No Data