The answer depends on your needs. Will the error message for a specific ever need to be updated? Will you need the ability to add new error code/message pairs dynamically? Will you need to localize the error messages?
The simplest method is just to hard the error code/message values using an IDictionary. That would mean that any updates would require you to recompile and redeploy your application.
Resource files would be another option. In this instance, you'd store the code/message pairs in the resource file, and your application would use the error code as the key to find the appropriate error message value. This would allow you to dynamically add code/message pairs and would make it easy to localize by creating a separate resource file for each language you need to support.
A third option, similar to the second, would be to store the error code/message pairs in a database table. Your application is, most likely, already talking to a database, so this may be a simpler option than resource files, at least from a deployment aspect. This would make localization more difficult, though.
If it were me, I would choose resource files if I thought there would be a need to localize in the future, and the database if I didn't.