0

I am not able to do any action in workbox, As most of the action redirect me back to the workbox page with port number in the url. And we have not opened that port number for internal access, so it taking us to site not available page. I want to know how to avoid the port number in the worbox page action url.

Example: If i select refresh option in the workbox. its making post call to sitecore/shell/Applications/Workbox.aspx?sc_bw=1 and in response i am getting url with port number like this below

{
  "commands": 
  [{
    "command":"SetAttribute",
    "value":"/temp/iconcache/people/16x16/user1.png",
    "id":"globalHeaderUserPortrait",
    "name":"src"
  },
  {
    "command":"SetPipeline",
    "value":"2D8C27809F764B95B6A1782D7A36DB57"
  }, 
  {
    "command":"SetLocation",
    "value":"https://sitename:44300/sitecore/shell/Applications/Workbox.aspx?sc_bw=1&reload=1"
  }]
}

After that response it will redirect me to the https://sitename:44300/sitecore/shell/Applications/Workbox.aspx?sc_bw=1&reload=1 url with port number in the response which is not accessible outside the server.

1
  • Do you have this port number specified somewhere (like in the site definition)? Commented Mar 29, 2019 at 19:21

1 Answer 1

1

I see the issue that you described. Actually the problem is in the Sitecore.Shell.Applications.Workbox.WorkboxForm class which represents the Workbox Form.

There are two methods:

    /// <summary>Refreshes the page.</summary>
    protected virtual void Refresh()
    {
      this.Refresh((Dictionary<string, string>) null);
    }

    /// <summary>Refreshes the page.</summary>
    /// <param name="urlArguments">The URL arguments.</param>
    protected void Refresh(Dictionary<string, string> urlArguments)
    {
      UrlString urlString = new UrlString(WebUtil.GetRawUrl());
      urlString["reload"] = "1";
      if (urlArguments != null)
      {
        foreach (KeyValuePair<string, string> urlArgument in urlArguments)
          urlString[urlArgument.Key] = urlArgument.Value;
      }
      Context.ClientPage.ClientResponse.SetLocation(WebUtil.GetFullUrl(urlString.ToString()));
    }

In general, the problem is in the Context.ClientPage.ClientResponse.SetLocation(WebUtil.GetFullUrl(urlString.ToString())) line. And is in WebUtil.GetFullUrl(urlString.ToString()) method particularly. This method always returns the URL with the port extension.

Then, looking at details of GetFullUrl method where we can find that it calls GetServerUrl:

public static string GetFullUrl(string url)
{
  Assert.ArgumentNotNull((object) url, nameof (url));
  return WebUtil.GetFullUrl(url, WebUtil.GetServerUrl());
}

The GetServerUrl method looks like:

public static string GetServerUrl()
{
  return WebUtil.GetServerUrl(false);
}

Where the false, is forcePort parameter, which is always 'false'.

Let's skip a calls chain and have a look at the final view of GetServerUrl method:

public static string GetServerUrl(Uri url, bool forcePort)
{
  if (url == (Uri) null)
    return string.Empty;
  string scheme = url.Scheme;
  string host = url.Host;
  string str1 = url.Port.ToString();
  string str2 = string.Format("{0}://{1}", (object) scheme, (object) host);
  if (forcePort || str1 != "80")
    str2 += string.Format(":{0}", (object) str1);
  return str2;
}

Looking at this method we can see that even forcePort is true, the URL will still include port as it is not equal to 80.

So, it is why you always have the port in your URL.

You can create your CustomWorkboxform class and inherit it from the 'WorkboxForm'. Then try to override protected new void Refresh(Dictionary<string, string> urlArguments) method (using new keyword as this method is not virtual). Then you will have to update Workbox.xml with new CustomWorkboxForm code behind implementation (\sitecore\shell\Applications\Workbox\Workbox.xml). There can be some another difficulties with overlapping other methods. But idea might work!

UPDATED: Final implementation of CustomWorkboxFrom looks like above:

using System;
using System.Collections.Generic;
using System.Linq;
using Sitecore;
using Sitecore.Text;
using Sitecore.Web;
using Sitecore.Workflows;
using Sitecore.Workflows.Simple;

namespace Test
{
    public class CustomWorkboxForm : Sitecore.Shell.Applications.Workbox.WorkboxForm
    {
        /// <summary>Gets or sets the offset(what page we are on).</summary>
        /// <value>The size of the offset.</value>
        private OffsetCollection Offset = new OffsetCollection();


        /// <summary>Refreshes the page.</summary>
        protected override void Refresh()
        {
            this.Refresh(null);
        }

        /// <summary>Refreshes the page.</summary>
        /// <param name="urlArguments">The URL arguments.</param>
        protected new void Refresh(Dictionary<string, string> urlArguments)
        {
            UrlString urlString = new UrlString(WebUtil.GetRawUrl());
            urlString["reload"] = "1";
            if (urlArguments != null)
            {
                foreach (KeyValuePair<string, string> urlArgument in urlArguments)
                    urlString[urlArgument.Key] = urlArgument.Value;
            }

            var url = WebUtil.GetFullUrl(urlString.ToString());
            var uri = new Uri(url);
            var clean = uri.GetComponents(UriComponents.AbsoluteUri & ~UriComponents.Port,
                UriFormat.UriEscaped);

            Context.ClientPage.ClientResponse.SetLocation(clean);
        }

        /// <summary>
        /// Workflow completion callback to refresh the counts of items in workflow states.
        /// </summary>
        /// <param name="args">The arguments for the workflow execution.</param>
        [UsedImplicitly]
        private void WorkflowCompleteStateItemCount(WorkflowPipelineArgs args)
        {
            IWorkflow workflowFromPage = GetWorkflowFromPage();
            if (workflowFromPage == null)
                return;
            int itemCount = workflowFromPage.GetItemCount(args.PreviousState.StateID);
            if (PageSize > 0 && itemCount % PageSize == 0)
            {
                int num = Offset[args.PreviousState.StateID];
                if (itemCount / PageSize > 1 && num > 0)
                    Offset[args.PreviousState.StateID]--;
                else
                    Offset[args.PreviousState.StateID] = 0;
            }
            Refresh(workflowFromPage.GetStates().ToDictionary((state => state.StateID), (state => Offset[state.StateID].ToString())));
        }


        private class OffsetCollection
        {
            public int this[string key]
            {
                get
                {
                    if (Context.ClientPage.ServerProperties[key] != null)
                        return (int)Context.ClientPage.ServerProperties[key];
                    UrlString urlString = new UrlString(WebUtil.GetRawUrl());
                    int result;
                    if (urlString[key] != null && int.TryParse(urlString[key], out result))
                        return result;
                    return 0;
                }
                set
                {
                    Context.ClientPage.ServerProperties[key] = (object)value;
                }
            }
        }
    }    
}

Unfortunately, if you still want to remove the port from URL, you need to include some implementation of private method defined in base class.

5
  • When creating custom class it also expect "WorkFlowCompleteStateItemCount"
    – Sundar Ram
    Commented Apr 1, 2019 at 18:43
  • @SundarRam I will have a look tomorrow how we can go around it. Commented Apr 1, 2019 at 18:45
  • thanks @Artsem Prashkovich
    – Sundar Ram
    Commented Apr 1, 2019 at 20:05
  • @SundarRam I've updated the answer. Please have a look. Commented Apr 2, 2019 at 13:39
  • thanks @Artsem Prashkovich
    – Sundar Ram
    Commented Apr 2, 2019 at 16:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.