I'm attempting to implement encrypted JSON properties using code from the question Using Json.NET, how can I encrypt selected properties of any type when serializing my objects?. I had originally set up a few "keys" as constants (Const
) in my application, but I recently had a thought of using another, more unique value to apply this encryption - a token that the user will be required to enter during the initial setup of the application. However, when I tried to change to using that token instead of my original keys, I'm encountering the Constant expression is required
message.
The original, working code for flagging the JSON properties for encryption looks like this:
<EditorBrowsable(EditorBrowsableState.Never)>
Private Class MyEndpoint
<JsonProperty("endpoint")> <JsonEncrypt(EndpointKey)>
Public Property Endpoint As Endpoint
End Class
<EditorBrowsable(EditorBrowsableState.Never)>
Private Class MyConnectionString
<JsonProperty("connection_string")> <JsonEncrypt(ConnectionStringKey)>
Public Property ConnectionString As ConnectionString
End Class
<EditorBrowsable(EditorBrowsableState.Never)>
Private Class MyUserCredential
<JsonProperty("credentials")> <JsonEncrypt(CredentialKey)>
Public Property Credential As Credential
End Class
I have the JsonEncryptAttribute
class like this:
<AttributeUsage(AttributeTargets.[Property] Or AttributeTargets.Field, AllowMultiple:=False)>
Public NotInheritable Class JsonEncryptAttribute
Inherits Attribute
Public Property EncryptionKey As Byte()
Public Sub New()
Me.EncryptionKey = GenerateKey(DefaultKey)
End Sub
Public Sub New(ByVal Password As String)
Me.EncryptionKey = GenerateKey(Password)
End Sub
Private Function GenerateKey(ByVal Password As String) As Byte()
Return SHA256.HashData(Encoding.UTF8.GetBytes(Password))
End Function
End Class
However, when I change the MyEndpoint
class definition to look like this:
<EditorBrowsable(EditorBrowsableState.Never)>
Private Class MyEndpoint
<JsonProperty("endpoint")> <JsonEncrypt(Settings.AppTokens("myapp"))>
Public Property Endpoint As Endpoint
End Class
...where AppTokens
is a property in the Settings
class that will be saved and read separately, the IDE balks and gives me the Constant expression is required
message. Based on the constructor for the JsonEncryptAttribute
class, I'm completely confused about why it would require the value to be a Const
in the first place.
However, looking at the documentation, I figure the error has to do with the fact that the AppTokens
(which is defined as a Dictionary(Of String, String)
) is the most likely culprit:
A
Const
statement does not properly initialize a constant, or an array declaration uses a variable to specify the number of elements.Error ID: BC30059
To correct this error
If the declaration is a
Const
statement, check to make sure the constant is initialized with a literal, a previously declared constant, an enumeration member, or a combination of literals, constants, and enumeration members combined with operators.If the declaration specifies an array, check to see if a variable is being used to specify the number of elements. If so, replace the variable with a constant expression.
I looked at the self-accepted answer to another question - Variable in enum attribute : constant expression is required - and tried to implement something similar but, unless I'm just doing it wrong (a definite possibility), it doesn't seem to work with class properties.
<JsonEncrypt(GetType(Settings), NameOf(Settings.AppTokens("myapp")))>
So, now I'm left with the following question(s):
Can anyone explain to me why this error is occurring here? Does it have something to do with the
JsonEncryptAttribute
's inheritance of the baseSystem.Attribute
?Is there a way to work around this by using a different object type or something? The
AppTokens
is read from a "base" JSON configuration file for the application, so whatever alternative would have to be compatible with that.