Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics 365 | Integration, Dataverse...
Unanswered

Difference between render a report in development environment vs UAT

(0) ShareShare
ReportReport
Posted on by Microsoft Employee

Hello!

I have justified a report using methods below, they basically add spaces between words to justify the text of a report. 

The problem is that in the development environment it works fine but in the UAT environment seems that method MeasureString it's not working as expected. There is a difference between calling " System.Drawing.Graphics::FromHwnd(System.IntPtr::Zero)" form Dev and from UAT?

Report from UAT:

pastedimage1599212928548v1.png

Report from DEV:

pastedimage1599213085250v3.png

-- Edited

Development is a Cloud-hosted environment and UAT is a tier-2 self-served environment.

---

Font font = new Font('Times New Roman', 11);

using (System.Drawing.Graphics g = System.Drawing.Graphics::FromHwnd(System.IntPtr::Zero))
{

         str stringFormated = formatClass.justifyParagraph(textToBeFormated, widthTextPDF, 0, font);

}

protected str justifyLine(str _text, int _width, Font _font = defaultFont)
{
         str test = 'test';

         List wordsList = new List(Types::String);

         wordsList = strSplit(_text, spaceChar);

         if (wordsList.elements() < 2)
         {
         return _text;
         }

         // The last word does not count as it does not have spaces on the right
         int numberOfWords = WordsList.elements() - 1;

         SizeF sizeTextWithoutSpaces = defaultGraphics.MeasureString(strReplace(_text, spaceChar, ''), _font);
         int wordsWidth = round(sizeTextWithoutSpaces.Width, 1);

         // Width of the hairSpace
         SizeF sizeTestPlusSpace = defaultGraphics.MeasureString(test + hairSpaceChar, _font);
         SizeF sizeTestWithoutSpace = defaultGraphics.MeasureString(test, _font);

         real hairSpaceCharWidth = sizeTestPlusSpace.Width - sizeTestWithoutSpace.Width;

         // Average spacing between each word
         int averageSpace = ((_width - wordsWidth) / numberOfWords) / hairSpaceCharWidth;

         // Aditional spaces to add
         real adjustSpace = (_width - (wordsWidth + (averageSpace * numberOfWords * hairSpaceCharWidth)));

         str spaces = '';
         str adjustedWords = '';

         for (int h = 0; h < averageSpace; h++)
         {
         spaces += hairSpaceChar;
         }

         ListIterator iterator = new ListIterator(wordsList);

         while (iterator.more())
         {
                  adjustedWords += iterator.value() + spaces;

                  //Adjust the spacing if there's a reminder
                  if (adjustSpace > 0)
                  {
                           adjustedWords += hairSpaceChar;
                           adjustSpace -= hairSpaceCharWidth;
                  }

                  iterator.next();

         }

         //Removes extra spaces at the end
         str resultWithoutSpace = subStr(adjustedWords, 1, strLen(adjustedWords) - averageSpace);

         return resultWithoutSpace;

}

public str justifyParagraph(str _text, int _controlWidth, int _listSymbolLength, Font _font = defaultFont)

{

         str result;

         List paragraphsList = new List(Types::String);

         paragraphsList = strSplit(_text, returnBreakLine);

         ListIterator iterator = new ListIterator(paragraphsList);
         ListIterator wordIterator;

         List words = new List(Types::String);

         str paragraph;
         str line;
         int paragraphWidth;
         str wordTmp;
         str resultStr;
         str listSymbol;

         boolean isFirstLine = true;

         while (iterator.more())
         {
                  paragraph = iterator.value();

                  line = '';
                  wordTmp = '';

                  SizeF size = defaultGraphics.MeasureString(paragraph, _font);

                  paragraphWidth = round(size.Width, 1);

                  if (paragraphWidth > _controlWidth)
                  {
                           //Get all paragraph words, add a normal space and calculate when their sum exceeds the constraints
                           words = strSplit(paragraph, spaceChar);

                           wordIterator = new ListIterator(words);

                           if (wordIterator.more())
                           {
                                    line = wordIterator.value() + spaceChar;
                           }

                           wordIterator.next();

                           while (wordIterator.more())
                           {
                                    wordTmp = wordIterator.value();

                                    str tmpLine = line + (wordTmp + spaceChar);

                                    SizeF tmpLineSize = defaultGraphics.MeasureString(tmpLine, _font);

                                    if (round(tmpLineSize.Width, 1) > _controlWidth)
                                    {                           
                                             if (_listSymbolLength && isFirstLine)
                                             {
                                                      [listSymbol, line] = this.getListSymbol(line, _listSymbolLength);
                                             }

                                             //Max lenght reached. Justify the line and step back
                                             resultStr = this.justifyLine(strRTrim(line), _controlWidth, _font);

                                             if (_listSymbolLength)
                                             {
                                                      resultStr = this.addTabSpace(isFirstLine, listSymbol) + resultStr;
                                             }

                                             result += resultStr + returnBreakLine;

                                             line = '';

                                             isFirstLine = false;
                                    }
                                    else
                                    {
                                             //Some capacity still left
                                             line += (wordTmp + spaceChar);
                                             wordIterator.next();
                                    }
                           }
                           //Adds the remainder if any
                           if (line != '')
                           {
                                    if (_listSymbolLength)
                                    {
                                             line = this.addTabSpace(isFirstLine, listSymbol) + line;
                                    }

                                    result += line + returnBreakLine;

                                    isFirstLine = true;
                           }
                  }
                  else
                  {
                           if (_listSymbolLength)
                           {
                                    if (isFirstLine)
                                    {
                                             [listSymbol, paragraph] = this.getListSymbol(paragraph, _listSymbolLength);
                                    }

                                    paragraph = this.addTabSpace(isFirstLine, listSymbol) + paragraph;
                           }

                           result += paragraph + returnBreakLine;

                           isFirstLine = true;
                  }

                  iterator.next();

         }

         return strRTrim(result);
}

protected container getListSymbol(str _text, int _listSymbolLength)
{
         str listSymbol = subStr(_text, 1, _listSymbolLength);
         str textResult = subStr(_text, _listSymbolLength + 1, strLen(_text));
         textResult = strLTrim(textResult);

         return [listSymbol, textResult];
}


protected str addTabSpace(boolean _isFirst, str _listSymbol)
{
         if (_isFirst)
         {
                  return _listSymbol + strRep(spaceChar, 4);
         }
         else
         {
                  return strRep(spaceChar, 4 + strLen(_listSymbol)) + hairSpaceChar;
         }
}

Thanks,

Anna

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Difference between render a report in development environment vs UAT

    UAT is a tier-2 self-served environment, so we cannot access to the VM to see the config files.

    Is there another thing that we can try to see if it's restricting the namespace?

  • David Jennaway Profile Picture
    David Jennaway 14,063 on at
    RE: Difference between render a report in development environment vs UAT

    SSRS might catch a security exception, rather than throwing it to the client. I'd suggest comparing the respective policy and config files on the SSRS servers. The most relevant ones are rsreportserver.config and rssrvpolicy.config in the Reporting Services\ReportServer folder. A file comparison should show any relevant differences.

    It's also worth checking the Reporting Services log files

  • Community Member Profile Picture
    Community Member Microsoft Employee on at
    RE: Difference between render a report in development environment vs UAT

    They are different servers.

    But if it's restricting the acces to the System.Drawing.Graphics namespace, it should have thrown an error, shouldn't it?

    Thanks,

    Anna

  • David Jennaway Profile Picture
    David Jennaway 14,063 on at
    RE: Difference between render a report in development environment vs UAT

    Are the Dev and UAT environments using the same servers as each other (i.e. 2 organisations in the same deployment), or different servers ? If they are different servers, then my guess is that there's a difference in the configuration of the Reporting Services servers; most likely security settings (the UAT server may be configured to use Code Access Security to restrict access to the System.Drawing.Graphics namespace), or possible settings of the account it runs under

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Announcing Our 2025 Season 1 Super Users!

A new season of Super Users has arrived, and we are so grateful for the daily…

Vahid Ghafarpour – Community Spotlight

We are excited to recognize Vahid Ghafarpour as our February 2025 Community…

Tip: Become a User Group leader!

Join the ranks of valued community UG leaders

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 292,516 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 231,399 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Product updates

Dynamics 365 release plans