3

I have some code which stores custom URLs in the IDTable. I am experiencing an issue with a site using the Greek language (el-GR) when part of the URL contains Greek characters e.g. χρώμα. My code contains the following where the variable key contains the string "χρώμα":

IDTableProvider provider = GetProvider();
var entry = new IDTableEntry(prefix, key, id, parentID, customData);
provider.Add(entry);

When reading the IDTable entry back out of the table I get "???µa".

I looked at the code in dotPeek and found that Sitecore is doing a regular insert from the add method, so I tried doing something directly in SSMS:

UPDATE [dbo].[IDTable]
SET [Key] = 'χρώμα'
WHERE ID = '{205DBEAC-B679-4CC8-804C-90AF6201EDB2}'

And I got the same result, so the issue must be in SQL Server. I noticed that the field type is varchar(255) rather than nvarchar(255) which I'm assuming is the reason for the problem. Is there any way to work around this limitation, perhaps encoding the string before saving/adding to the IDTable?

2
  • Maybe the collation of your database is not capable of storing these characters. Run SELECT DATABASEPROPERTYEX('SITECORE_MASTER', 'Collation') SQLCollation; to find out what the collation is. – Thomas D Nov 24 '16 at 11:22
  • I don't really want to play around with the database, as that is not supported by Sitecore. – Matthew Dresser Nov 24 '16 at 11:23
3

The obvious answer would be, to just update the field to NVARCHAR - from an application layer perspective, nothing in Sitecore should really care about this.

That said; I understand the reasons for not wanting to do this.

Your alternative then, becomes to convert in and out of Unicode when adding and getting keys. There are a number of ways to achieve this; I propose BASE64.

Encode

public static string Base64Encode(string plainText) {
  var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
  return System.Convert.ToBase64String(plainTextBytes);
}

Decode

public static string Base64Decode(string base64EncodedData) {
  var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
  return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}

And you would then need to update your code.

IDTableProvider provider = GetProvider();
var entry = new IDTableEntry(prefix, Base64Encode(key), id, parentID, customData);
provider.Add(entry);

And also when getting, obviously.

Base64 snippet sourced here: https://stackoverflow.com/questions/11743160/how-do-i-encode-and-decode-a-base64-string

edited to add

You could of course write your own version of Sitecore.Data.SqlServer.SqlServerIDTable and configure it here. I've never done it, and it seems way too much work for what it would be worth.

  <IDTable type="Sitecore.Data.$(database).$(database)IDTable, Sitecore.Kernel" singleInstance="true">
    <param connectionStringName="master" />
    <param desc="cacheSize">2500KB</param>
  </IDTable>

You would need to override the following methods:

  • public override void Add(IDTableEntry entry)
  • public override void Add(IDTableEntry entry)
  • public override IDTableEntry GetID(string prefix, string key)
  • public override IDTableEntry[] GetKeys(string prefix, ID id)
  • public override IDTableEntry[] GetKeys(string prefix)
  • public override void Remove(string prefix, string key)

Doesn't seem worth it, in my opinion.

1
  • I arrived at the same conclusion also! Thanks – Matthew Dresser Nov 24 '16 at 12:14

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.