cancel
Showing results for 
Search instead for 
Did you mean: 

Compiler error at line 64: Unexpected character '$'

AndreiCozma
Level 3
Hi All,

I have a global code stage in C# . The code works perfect in Visual Studio but when copying over to BP gives the following error
Page: Initialise
Stage: Stage1
Type: Error
Action: Validate
Description: Compiler error at line 64: Unexpected character '$'
Repairable: No
 However removing the $ sign makes things worse as it ends up afterwards saying that a number of brackets are missing

Anyone witnessed this error_
class Credential
{
// accout region, use 'default' value unless being instructed otherwise
private const string d_region = "default";
// Once created each token will be valid only for the following specified period(in seconds).
// This value is ajustable on client side, but note that increasing this value too much
// might not suffice for security concerns, as well as too little value could lead to
// JWT token invalidation before it being received by the beap server due to network delays.
// You can adjust this value for your need or use default value unless you definitely know
// that you need to change this value.
private const int d_lifetime = 25;
/// <summary>
/// Provides access to client id parsed from credential.txt file.
/// </summary>
[JsonProperty("client_id")]
public string ClientId { get; set; }
/// <summary>
/// Accepts client secret form json deserializer and decodes it to bytes.
/// </summary>
[JsonProperty("client_secret")]
public string ClientSecret { set { DecodedSecret = FromHexString(value); } }
/// <summary>
/// Provides access to decoded client secret.
/// </summary>
public byte[] DecodedSecret { get; private set; }
/// <summary>
/// Converts hexadecimal string to bytes.
/// </summary>
/// <param name="s">Input hexadecimal string.</param>
/// <returns></returns>
static private byte[] FromHexString(string input)
{
return Enumerable.Range(0, input.Length)
.Where(charIdx => charIdx % 2 == 0)
.Select(charIdx => Convert.ToByte(input.Substring(charIdx, 2), 16))
.ToArray();
}
/// <summary>
/// Loads credentials from credential.txt file.
/// </summary>
/// <param name="d_credentialPath">Path to credential.txt file.</param>
/// <returns></returns>
public static Credential LoadCredential(string d_credentialPath = "credentials/credential.txt")
{
try
{
using StreamReader fileInput = new StreamReader(d_credentialPath);
using var jsonInput = new JsonTextReader(fileInput);
var clientCredential = new JsonSerializer().Deserialize<Credential>(jsonInput);
string clientSecret = Convert.ToBase64String(clientCredential.DecodedSecret);

Console.WriteLine($"client id: {clientCredential.ClientId}");
Console.WriteLine($"client secret (base64 encoded): {clientSecret}");
Console.WriteLine();

return clientCredential;
}
catch (JsonReaderException error)
{
Console.Error.WriteLine($"Cannot read credential file, probably not in JSON format: {error.Message}");
}
catch (UnauthorizedAccessException)
{
Console.Error.WriteLine($"Cannot access credential file, check file permissions.");
}
catch (ArgumentException error)
{
Console.Error.WriteLine($"{error.Message}");
}
catch (IOException error)
{
Console.Error.WriteLine($"Cannot open credential file \nerror description: {error.Message}");
}
Environment.Exit(-1);
return null;
}

/// <summary>
/// Creates new JWT token for the given input request parameters.
/// </summary>
/// <param name="host">the beap host being accessed.</param>
/// <param name="path">URI path of the accessed endpoint.</param>
/// <param name="method">HTTP method used to access the endpoint.</param>
/// <returns></returns>
internal string CreateToken(string host, string path, string method)
{
string guid = Guid.NewGuid().ToString();
// Get unix timestamp
long issueTime = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
// Create key for JWT signature
SymmetricSecurityKey securityKey = new SymmetricSecurityKey(DecodedSecret);
// Define JWT signing key and algorythm
SigningCredentials signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
// Create JWT header container object
var header = new JwtHeader(signingCredentials);
// Create JWT payload container object
var payload = new JwtPayload
{
{ JwtRegisteredClaimNames.Iss, ClientId },
{ JwtRegisteredClaimNames.Iat, issueTime },
{ JwtRegisteredClaimNames.Nbf, issueTime },
{ JwtRegisteredClaimNames.Exp, issueTime + d_lifetime },
{ "host", host },
{ "path", path },
{ "region", d_region },
{ "jti", guid },
{ "method", method },
{ "client_id", ClientId }
};
// Create JWT token object
JwtSecurityToken jwtToken = new JwtSecurityToken(header, payload);
// Serialize JWT token object to base64 encoded string
return new JwtSecurityTokenHandler().WriteToken(jwtToken);
}
}







------------------------------
Andrei Cozma
Data
Zurich
Europe/Madrid
------------------------------
3 REPLIES 3

KrishnaA
Staff
Staff
Hi Andrei,

When moving the code to BP, suggest replacing the Console.Error.WriteLine lines with the throw exception as you would not have anything to write to in BP environment.

Best regards,


------------------------------
Krishna A
Blue Prism
------------------------------
Krishna A [CompanyName]

NicholasZejdlik
Level 9
It may be the version of C# that Blue Prism is targeting; string interpolation was added in version 6 of C#, and I think Blue Prism is targeting version 5.

------------------------------
Nicholas Zejdlik
RPA Developer
------------------------------

Hi Andrei,

To expand on the last comment from Nicholas a little, Blue Prism 6.8 included an update to the code compiler used by code stages that moves the targeted C# version to 7 (this can be found under US-7483 in the release notes), but prior to this Nicholas is correct and it would be C# version 5 that the code stages would be using.

Regards,
Rob

------------------------------
Robert Nicklin
Senior Product Owner
Blue Prism
Warrington, England
------------------------------
Robert Nicklin Product Manager Blue Prism Warrington, England