Sitecore Registry Editor

Posted 21 May 2018 by Marek Musielak

sitecore registry editor logo

Sitecore Registry is a place where Sitecore stores user data, e.g. data related to the user editing preferences and choices. From time to time, people ask how this data can be altered. The answer is to use Registry.SetValue("/Current_User/SOME_KEY", value). Sounds easy but:
a) How to know what key should be used?
b) How to make sure that what we set is stored?
c) What other things can be set there?
To help with all those questions, I've created a simple SitecoreRegistryEditor.aspx page.

How to start using Sitecore Registry Editor?

Download SitecoreRegistryEditor.aspx page and move it to your Content Management server to the chosen directory of your Sitecore application. Then open SitecoreRegistryEditor.aspx page in a browser, login and you will see a screen similar to:

sitecore registry editor

What can I do using Sitecore Registry Editor?

There are 4 things you can do using Sitecore Registry Editor:

  1. See all the keys and their values stored in Sitecore Registry.
  2. Remove any of the Sitecore Registry entries.
  3. Edit any of the Sitecore Registry entries.
  4. Add new Sitecore Registry entry.

What kind of data is stored in Sitecore Registry?

Every time user decides to show, hide, check or slide a thing in Sitecore backend, this information is saved in Sitecore Registry, e.g:

  • Publish/Languages - pipe delimited list of languages checked in the Publish wizard
  • RecentIcons - list of recently selected icons
  • UserOptions.View.ShowBucketItems - show or hide bucket items
  • Rebuild Search Index/Selected - indexes selected for rebuilding in Indexing Manager
  • Panes/P{SOME_GUID} - workflows preselected in Workbox
  • UserOptions.ContentEditor.ShowRawValues - show raw values in Content Editor
  • History/Add.From.Template - which template will be preselected when using "Insert from template" option
  • any many many others.

So I just copy aspx page and no dlls are needed?

Yes, I put all the code inside that aspx page. Yes, I know it's not the cleanest solution but it works and it's easy to see what is in the code. What is more, you can restrict access to this page for specified roles (sitecore\Sitecore Client Users by default) and filter out Sitecore Registry entries which don't interest anyone (like "Content Editor/Field Size/" and "Listviews").

Which Sitecore version I can use?

I tested Sitecore Registry Editor with Sitecore 8.2. But I don't see anything version specific in the code, except from casting User.Profile.SerializedData to Dictionary<string, string>. In older Sitecore versions NameValueCollection was used instead. Feel free to modify any line of the code if needed.

Where I can download Sitecore Registry Editor?

Here: SitecoreRegistryEditor.aspx or alternatively copy the code from here:

<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="Sitecore.Caching" %>
<%@ Import Namespace="Sitecore.Sites" %>
<%@ Import Namespace="Sitecore.Web.UI.HtmlControls" %>

<script runat="server">
    private const string AllowedRole = @"sitecore\Sitecore Client Users";
    private static readonly string[] Filters = { "Content Editor/Field Size/", "Listviews" };

    private string _prefix;
    private string Prefix { get { return _prefix ?? (_prefix = "registry_/" + Sitecore.Context.GetUserName().ToLowerInvariant() + "/"); } }

    private SiteContext _siteContext;
    private SiteContext SiteContext { get { return _siteContext ?? (_siteContext = SiteContext.GetSite("shell")); } }

    public void Page_Load(object sender, EventArgs args)
    {
        if (Sitecore.Context.User != null && Sitecore.Context.User.IsAuthenticated &&
            (string.IsNullOrEmpty(AllowedRole) || Sitecore.Context.User.IsInRole(AllowedRole) || Sitecore.Context.User.IsAdministrator))
        {
            if (!IsPostBack)
            {
                BindRepeater();
            }
        }
        else
        {
            Response.Redirect("/sitecore/login?returnUrl=" + HttpUtility.UrlEncode(Request.Url.PathAndQuery));
        }
    }

    private void BindRepeater()
    {
        rpt.DataSource =  ((Dictionary<string, string>)Sitecore.Context.User.Profile.SerializedData)
            .Where(entry => Filters.All(f => !entry.Key.Contains(f)))
            .Where(entry => entry.Key.StartsWith("/" + Sitecore.Context.GetUserName().ToLowerInvariant() + "/"))
            .Where(entry => !string.IsNullOrEmpty(entry.Value))
            .OrderBy(pair => pair.Key);
        rpt.DataBind();
    }

    private void RemoveCachedValue(object source, CommandEventArgs commandEventArgs)
    {
        var cacheKey = (string) commandEventArgs.CommandArgument;
        using (new SiteContextSwitcher(SiteContext))
            Registry.SetValue("/Current_User/" + cacheKey, string.Empty);
        CacheManager.GetRegistryCache(SiteContext).Remove(Prefix + cacheKey);
        BindRepeater();
    }

    private void SaveCacheValue(object sender, EventArgs e)
    {
        if (!string.IsNullOrEmpty(txtKey.Text))
        {
            string key = txtKey.Text;
            string value = txtValue.Text;

            if (key.StartsWith(Prefix))
            {
                key = key.Substring(Prefix.Length - 1).Trim();
            }

            using (new SiteContextSwitcher(SiteContext))
                Registry.SetValue("/Current_User/" + key.TrimStart('/').Trim(), value);
            BindRepeater();
            txtKey.Text = txtValue.Text = string.Empty;
        }
    }

</script>

<html>
    <head>
        <title>Registry editor</title>
    </head>
    <body>
        <form runat="server">
            <h1>Registry editor</h1>
            <table cellspacing="1" cellpadding="1" border="1">
                <tr>
                    <th style="width: 48%;">Key</th>
                    <th style="width: 48%;">Value</th>
                    <th style="width: 4%;">&nbsp;</th>
                </tr>
                <asp:Repeater runat="server" id="rpt" ItemType="System.Collections.Generic.KeyValuePair`2[System.String,System.String]" OnItemCommand="RemoveCachedValue">
                    <ItemTemplate>
                        <tr style="<%# Container.ItemIndex % 2 == 1 ? string.Empty : "background-color: #ddd" %>">
                            <td><%#: Item.Key.Substring(Item.Key.IndexOf('/', 10)).Trim('/') %></td>
                            <td><%#: Item.Value %></td>
                            <td style="text-align: center">
                                <asp:LinkButton ForeColor="Red" runat="server" OnCommand="RemoveCachedValue" CommandArgument="<%#: Item.Key.Substring(Item.Key.IndexOf('/', 10)).Trim('/') %>">&#215;</asp:LinkButton>
                            </td>
                        </tr>
                    </ItemTemplate>
                </asp:Repeater>
                <tr>
                    <td><asp:TextBox runat="server" id="txtKey" Width="100%" /></td>
                    <td><asp:TextBox runat="server" id="txtValue" Width="100%" /></td>
                    <td style="text-align: center">
                        <asp:LinkButton ForeColor="Green" runat="server" OnClick="SaveCacheValue">Save</asp:LinkButton>
                    </td>
                </tr>
            </table>  
        </form>
    </body>
</html>

You've read the whole article? Thanks! Now let me know what do you think about it? Useful? Boring? Doesn't work for you? Leave a comment below.

Comments? Find me on or Sitecore Chat