5

I would like to refresh a Sitecore item after editing it programmatically.

Scenario: An Action of a workflow opens a dialog, does some operation and on clicking the OK button I want to refresh the Item on the Content Editor.

I tried the following approaches but they didn't work.

string load = string.Concat("item:load(id=", workflowItem.ID, ",language=", workflowItem.Language, ",version=", workflowItem.Version, ")");
Context.ClientPage.SendMessage(this, load);

string refresh = $"item:refreshchildren(id={workflowItem.ID})";
Context.ClientPage.ClientResponse.Timer(refresh, 12);

Your help is highly appreceiated.

Code Used for Custom Action:

public class ShowAuthenticationDialog
{
    public void Process(WorkflowPipelineArgs args)
    {
        CreateContext(args);
    }

    private void CreateContext(WorkflowPipelineArgs args)
    {
        string controlUri = UIUtil.GetUri("control:AuthenticationDialog");
        Item item = args.DataItem;
        string nextStateId =  args.CommandItem.Fields["Authentication Next State"]?.GetValue(true);

        UrlString controlUrlString = new UrlString($"{controlUri}&ItemId={item.ID}&WorkflowNextStateId={nextStateId}");

        SheerResponse.ShowModalDialog(controlUrlString.ToString());

        string load = $"item:load(id={item.ID},language={item.Language},version={item.Version})";
        Context.ClientPage.SendMessage(this, load);
    }
}

Code for the OnOk method

    protected override void OnOK(object sender, EventArgs args)
    {
        Assert.ArgumentNotNull(sender, "sender");
        Assert.ArgumentNotNull(args, "args");

        string itemId = WebUtil.GetQueryString("ItemId");
        Database database = Factory.GetDatabase("master");
        Item workflowItem = database.GetItem(itemId);

        //TODO: Pass credentials to authentication service
        if (true)
        {
            string newStateId = WebUtil.GetQueryString("WorkflowNextStateId");
            string newState = database.GetItem(newStateId)?.DisplayName;

            if (!string.IsNullOrWhiteSpace(newState))
            {
                ChangeWorkflowState(workflowItem, newState);

                string load = $"item:load(id={workflowItem.ID},language={workflowItem.Language},version={workflowItem.Version})";
                Context.ClientPage.SendMessage(this, load);

                string refresh = $"item:refreshchildren(id={workflowItem.ID})";
                Context.ClientPage.ClientResponse.Timer(refresh, 12);

                //TODO: Add History
            }
        }

        base.OnOK(sender, args);
    }
  • I think you're asking how to clear all caches for a particular item? stackoverflow.com/q/10220196/1102452 – Mark Gibbons Feb 13 '19 at 0:17
  • For instance, If I change the Workflow state of an item programmatically, then I want that change to be shown on the ContentEditor without the content editor having to refresh the page or switch between the items. I hope this clears your question. – Abhi Feb 13 '19 at 0:31
  • We will need to see the rest of your code. I’ve used the two approaches you listed but they are sensitive to how the code is called. Are you able to post all of your code with the sensitive data stripped out? – jrap Feb 13 '19 at 0:33
  • @Abhi it would be helpful if you added this code to your original post so it's properly formatted. – Dylan Young Feb 13 '19 at 0:51
4

After hours of investigating the issue, I found the problem that I am supposed to send the load command using ClientResponse instead of SendMessage.

Thanks, everyone for your help.

 string load = $"item:load(id={workflowItem.ID},language={workflowItem.Language},version={workflowItem.Version})";
 Context.ClientPage.ClientResponse.Timer(load, 2);
0

Try to add a Context.ClientPage.ClientResponse.Alert("test this should work");in your OnOk Methode.

If this is not working you call it the wrong way. Put a Context.ClientPage.Start((object)this, "Run", args.Parameters);in your OnOK methode.

And somethings like this:

protected new void Run(ClientPipelineArgs args) {
    Log.Info("Run method is called");

    some code to check and get the workflowItem

    Context.ClientPage.ClientResponse.Alert("Hello, just for testing");

    string load = $"item:load(id={workflowItem.ID},language={workflowItem.Language},version={workflowItem.Version})";
    Context.ClientPage.SendMessage(this, load);

    string refresh = $"item:refreshchildren(id={workflowItem.ID})";
    Context.ClientPage.ClientResponse.Timer(refresh, 2);
}
  • I tested both implementations and both didn't work in my scenario. I was able to see the alert messages but the ribbons and the workflow state did remain the same even after the send message is passed. How is the item switch refresh is different from this load? When I switch between the items the ribbons and the workflow changes does reflect. – Abhi Feb 13 '19 at 16:19
  • So from my observation, I feel that the refresh is happening but the content is pulled from the cache and probably I need to clear the cache but what I am not sure about is how to clear a cache specific to an item. – Abhi Feb 13 '19 at 17:28
  • Not sure if this still work on Sitecore 9, but it is based on this blog community.sitecore.net/technical_blogs/b/sitecorejohn_blog/… worked for me. you can decompile the change icon to see what code Sitecore use. – Jan Bluemink Feb 13 '19 at 20:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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