Creating a link using an 18 character ID

I have an 18 character SFDC ID. I was under the impression that I should be able to create a link to that record using the following pattern: https://<org server>.salesforce.com/<id>

For example: https://na12.salesforce.com/00TU000000Nf5NP

That link works fine for me. However, when I try to link to the same object using the 18 character, case insensitive ID (ex. https://na12.salesforce.com/00tu000000nf5npmaz), I get the following error:

Insufficient Privileges

You do not have the level of access necessary to perform the operation
you requested. Please contact the owner of the record or your
administrator if access is necessary.

What exactly is the problem? If all I have is the 18 character ID, how can I create a link back to the correct SalesForce record?

Answer

I’m not sure that the case insensitive Ids work like that. With your all lowercase ID I’m guessing Salesforce is looking for an OpportunityShare (keyPrefix 00t) rather than a Task (00T). Odd that they aren’t using the suffix information.

The suffix is enough to make the ID appear to be insensitive in something like Excel, but it doesn’t mean you can convert it all to lowercase in Salesforce.

Try 00TU000000Nf5NPMAZ on the URL.


Writing something to revert the casing just seemed like too much fun to be left undone.

This is in C#, but I’ve tried to avoid things like LINQ and framework classes (BitArray) to make it more language agnostic. It does bloat it a bit, but hopefully you get the idea. There are several areas that would benefit from some additional error checking.

private static char[] characterMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345".ToCharArray();

private static bool[] BitPatternForChar(char c)
{
    c = Char.ToUpper(c);

    byte characterMapIndex = byte.MinValue;
    for(byte i = 0; i<characterMap.Length; i++)
    {
        if(characterMap[i] == c)
        {
            characterMapIndex = i;
            break;
        }
    }

    // Get the Bit Pattern for the byte
    bool[] result = new bool[5];
    for (int bitNumber = 0; bitNumber < result.Length; bitNumber++)
    {
        result[bitNumber] = (characterMapIndex & (1 << bitNumber)) != 0;
    }
    return result;
}

public static string RepairCasing(string lowercaseInsenstiveId)
{
    if (string.IsNullOrEmpty(lowercaseInsenstiveId))
    {
        throw new ArgumentNullException("lowercaseInsenstiveId");
    }
    else if (lowercaseInsenstiveId.Length != 18)
    {
        throw new ArgumentException("lowercaseInsenstiveId should be 18 characters", "lowercaseInsenstiveId");
    }

    List<bool> toUpperBits = new List<bool>(15);

    bool[] isUpperCaseChar = BitPatternForChar(lowercaseInsenstiveId[15]);
    toUpperBits.AddRange(isUpperCaseChar);

    bool[] isUpperCaseChar2 = BitPatternForChar(lowercaseInsenstiveId[16]);
    toUpperBits.AddRange(isUpperCaseChar2);

    bool[] isUpperCaseChar3 = BitPatternForChar(lowercaseInsenstiveId[17]);
    toUpperBits.AddRange(isUpperCaseChar3);

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 15; i++)
    {
        Char c = lowercaseInsenstiveId[i];

        if (toUpperBits[i])
        {
            c = Char.ToUpper(c);
        }
        else
        {
            c = Char.ToLower(c);
        }
        sb.Append(c);
    }
    sb.Append(lowercaseInsenstiveId.Substring(15, 3).ToUpper());
    return sb.ToString();
}

Attribution
Source : Link , Question Author : Ryan Elkins , Answer Author : Daniel Ballinger

Leave a Comment