Using MacroResolver.Resolve() to resolve a foreach statement?

Matthew Neal asked on August 21, 2017 09:12

With the help of some of the pro's here on Devnet, I've managed to solve most of the last few issues I've been having with Kentico. However, I have one last thing that's doing my head in.

I have the following code in my 'layout.master.cs' file:

  public string absoluteURL = MacroResolver.Resolve( "{% CurrentDocument.AbsoluteURL %}" );
  public string pageDescription = MacroResolver.Resolve( "{% CurrentPageInfo.DocumentPageDescription %}" );

Which works fine when called in the 'layout.master' .aspx file like this:

<meta property="og:url" content="<%=absoluteURL%>" />
<meta property="og:description" content="<%=pageDescription%>" />

however, I have a foreach loop for the image attachments per page and I believe I'm doing something wrong here. This is what it looks like in the .cs file: public string heroImageGUID = MacroResolver.Resolve( "{% foreach (attachment in Documents[NodeALiasPath].AllAttachments) {\"<a href='/getattachment/\" + attachment.AttachmentGUID + \"/attachment.aspx'>\" + attachment.AttachmentName + \"</a><hr />\";} %}" );

And like this in the .aspx file: <%=heroImageGUID%>

...sooooo where am I going wrong? Do I need to escape the " or ' or even (?

I'm quite new to c# and Kentico so some hand holding would be delightful! If not, just point me in the right direction and I'll be forever grateful!

Correct Answer

Trevor Fayas answered on August 21, 2017 15:21

I'm going to guess that since that macro accesses the documents and attachments, it is going to need security context to run. Some macros require you to have accesses (usually a hashed # is added to the end and Kentico adds in the context, calling it like this though look at the method and i think the Resolver method allows you to add another parameter that you can set your security context).

Your syntax is correct otherwise, in Kentico go to System > Macros > Console, here you can type in your macro and test it, i replicated and used yours and i got the proper return result.

I would also recommend you look into Kentico Portal method, it's recommended because a lot of what you are doing can be done without code using Webparts.

0 votesVote for this answer Unmark Correct answer

Recent Answers

Matthew Neal answered on August 23, 2017 06:39

Thanks for your reply Trevor, again, it looks like you're correct. The only issue I have, is changing the development model won't be easy - the site I'm working on has almost 1000 pages! I guess I'll get this sorted, then look into what I'll need to do to change the site later down the track. Unfortunately we just rebranded the whole site too.

0 votesVote for this answer Mark as a Correct answer

Trevor Fayas answered on August 23, 2017 16:01

Good luck Matthew! Good news is if the Site is ASPX or ASPX+Portal, it's not extremely difficult to rework, i've converted over a couple sites already.

First if you have ASPX (Not ASX+Portal), try adding the webpart zones to your aspx files and changing the page template from ASPX to ASPX+Portal, that at least will allow you to start using webparts / widgets.

To go purely portal, the process is first to rework the master page (copy the master page's aspx layout into the "Layout" Tab of a page template, and replace each piece with webparts).

After you do that, you will just one by one go through the page templates (not pages, just the page templates) and copy the ASPX code to the Layout tab, add in webpart zones and replace the functionality.

Keep in mind if there is any logic in the back end (aspx.cs) file, you can add this to your portal page templates through server script tag in the layout, or a custom 'webpart' that does the logic in a control.

Worth the transition.

0 votesVote for this answer Mark as a Correct answer

Matthew Neal answered on August 24, 2017 04:50

Oh cool - that doesn't sound too hard. There's a lot less templates then there are pages!

Could I hassle you with one more thing? like you mentioned above in your first reply, it does appear to be a security problem. The macros work when placed in the head web part, but not if I use the MacroResolver.Resolve() function in the layout.master.cs file. I'm getting the following error:

Security check of the expression ' foreach (attachment in Documents[NodeALiasPath].AllAttachments) { "<meta property='og:image' content='http://*******.dev/getattachment/" + attachment.AttachmentGUID + "/attachment.aspx'" + "/>"; } ' didn't pass. The expression was signed by user ''. Remove the signature and re-save the expression by a user with proper permissions.

I searched for hours for a solution and none of them seemed to work. It appears to be because it's trying to be run by user 'public' (not in the code above, there's no user at all now for some reason) when it needs to be run as administrator maybe?

Alternatively I'm just going to have to search for an alternative method - but I'm out of ideas on what to search for :(

0 votesVote for this answer Mark as a Correct answer

Trevor Fayas answered on August 24, 2017 15:29

I'm guessing you are using the current user for the signature, which doesn't have permission for this call, you need to get the administrator's userinfo object to pass to the macro security, then it should workl, post your macro call and i'll verify.

0 votesVote for this answer Mark as a Correct answer

Matthew Neal answered on August 29, 2017 07:17

public string heroImageGUID = MacroResolver.Resolve( "{% foreach (attachment in Documents[NodeALiasPath].AllAttachments) { \"<meta property=\'og:image\' content=\'http://******.dev/getattachment/\" + attachment.AttachmentGUID + \"/attachment.aspx\'\" + \"/>\"; } @%} " );

And on the page:

<meta property="og:image" content="<%=heroImageGUID%>">

Is there anything you require?

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.