Skip to main content

I will gloss over the absurdity, for now, of a “low code/no code” platform requriing this kind of technical solution to do something as simple as redirect the user to an external website by clicking a button:

https://asiablog.acumatica.com/2017/08/redirecting-to-external-page-from-button.html

 

I have implemented the solution described in the article, with a button in the Sales Order toolbar to launch a custom item lookup screen (it’s an external webpage that lives outside Acumatica and communicates to Acumatica via webhook).

That all works well, except for one thing. If I try to pass any query parameters in the url (standard http get request….i.e Redirect8: http://www.mysite.com?myqueryparam=bob, then for whatever reason the query parameters are all stripped when the page loads. This seems to be happening with some sort of Javascript perhaps (I haven’t traced the source yet), because it’s very clear that the url is requested with query params, but then ends up without them. If I load the page from outside Acumatica with the same query params, then everything is fine.

Can someone explain why this is happening and if there is a way to pass query parameters to the redirect exception so that they won’t be stripped? Also, can someone please document this functionality officially outide of the current documentation, which is a blog post?…… https://asiablog.acumatica.com/2017/08/redirecting-to-external-page-from-button.html

 

 

 

Hello @rosenjon 

There is a way to do this with special exception classes defined in Acumatica, as the article mentions:

  • PXRedirectRequiredException opens the specified application page in the same window or a new one. By default, the user is redirected in the same window.
  • PXPopupRedirectException opens the specified application page in a pop-up window.
  • PXReportRequiredException opens the specified report in the same window or a new one. By default, the report opens in the same window.
  • PXRedirectWithReportException opens two pages: the specified report in a new window, and the specified application page in the same window.
  • PXRedirectToUrlException opens the webpage with the specified external URL in a new window. This exception is also used for opening an inquiry page that is loaded into the same window by default.

These are documented here: https://help-2022r1.acumatica.com/(W(62))/Help?ScreenId=ShowWiki&pageid=1fe245c2-b7de-42c7-a16c-217dc369c802
 

If opening your app in an external window, you could use PXRedirectToUrlException. Since Acumatica blocks externals sites from loading, it will ignore any WindowMode you set and will always open the url in a new window.

If you need to load the url inside the Acumatica frame, you would need to use the workaround the article shows. This is not documented because is not a recommended practice and you are basically using internal behavior for your benefit. This could change in a newer release, breaking your customization.


I did a simple action with both examples and query parameters worked as expected.

New window:

Using System.Web;

//...

public PXAction<SOOrder> openLink;

bPXButton(CommitChanges = true, DisplayOnMainToolbar = true), PXUIField(DisplayName = "Open Link", MapEnableRights = PXCacheRights.Select, Visible = true)]
protected virtual IEnumerable OpenLink(PXAdapter adapter)
{
// You should encode any part of the URL that could be invalid if used directly
string url = $"https://en.wikipedia.org/w/index.php?title=" + Uri.EscapeDataString("Acumatica") + "&param2=" + Uri.EscapeDataString("Another parameter");

throw new PXRedirectToUrlException(url, "App");

}

Inside Acumatica:

Using System.Web;

//...

public PXAction<SOOrder> openLink;

bPXButton(CommitChanges = true, DisplayOnMainToolbar = true), PXUIField(DisplayName = "Open Link", MapEnableRights = PXCacheRights.Select, Visible = true)]
protected virtual IEnumerable OpenLink(PXAdapter adapter)
{
// You should encode any part of the URL that could be invalid if used directly
string url = $"https://en.wikipedia.org/w/index.php?title=" + Uri.EscapeDataString("Acumatica") + "&param2=" + Uri.EscapeDataString("Another parameter");

throw new Exception($"Redirect0:{url}");

}

Take note that in order to be able to open sites inside an iframe, that site should allow it (I’m using wikipedia.com because it works, google.com for example, doesn’t), Most modern browsers will refuse to load any site that does not allow it explicitly.


Yes, PXRedirectToUrlException is the correct answer.

  string externalLink = "http://localhost/test.html?ordernbr=" + ordernbr + "&customername=" + Uri.EscapeDataString(customer_name);

throw new PXRedirectToUrlException(externalLink, PXBaseRedirectException.WindowMode.NewWindow, "Redirect:" + externalLink);

 

The only part of you answer that isn’t 100% right is that HttpUtility.UrlEncode does not properly urlencode strings with spaces (will use + instead of %20). Uri.EscapeDataString is better for url encoded get variables that have spaces, etc in them.


You are correct, I’ll edit my code in case someone wants to use it.


One other note here. this little description is not technical documentation:

https://help-2022r1.acumatica.com/(W(62))/Help?ScreenId=ShowWiki&pageid=1fe245c2-b7de-42c7-a16c-217dc369c802

It would be fine as the initial summary of an article about what this function does and how it is used. But there are 7 overloads just for the PXRedirectoUrlException flavor of this. These overloads, and indeed the object types required to pass into the function, are only found in Acuminator, which is basically just mining the code base for information. I am trying to point out that searching the code base is not documentation. What format does the “format” variable take in this overload of this method? The only was to find any example is to search through the code base….

        public PXRedirectToUrlException(string url, WindowMode newWindow, string format, params objecta] args);

 

        public PXRedirectToUrlException(string url, string message);
        public PXRedirectToUrlException(SerializationInfo info, StreamingContext context);
        public PXRedirectToUrlException(string url, string format, params objectg] args);
        public PXRedirectToUrlException(string url, WindowMode newWindow, string message);
        public PXRedirectToUrlException(string url, WindowMode newWindow, string message, bool repaintControls);
        public PXRedirectToUrlException(string url, WindowMode newWindow, string format, params objecti] args);
        public PXRedirectToUrlException(string url, WindowMode newWindow, bool suppressFrameset, string message);
        public PXRedirectToUrlException(string url, WindowMode newWindow, bool suppressFrameset, string format, params objectp] args);


Reply