I was wondering if anyone had any input on the best practice of where to store static error strings in a C# application. I have a visual studio 2010 solution that has 5 projects and have defined several constant error messages to be returned via a WCF REST web service in the form of a message.
My current errors I have defined (hard-coded) are in the following format (CODE, MESSAGE):
999 - Your request could not be processed with the parameters specified.
I am not asking how to create custom classes derived from the Exception class because these errors are returned after corresponding Exceptions are raised to keep the AppPool from faulting.
Some ideas I was pondering storing the messages in: XML, Flat File, SQLite, and so on.
Does anyone have a preference and if so, why?
Thank you,
Jeffrey Kevin Pry
I personally store these things in the projects Resources file, and then retrieve them when I need them. Doing it this way also makes it a lot easier to change them, for example if you needed the system to use another language all you'd do is switch the resources file for one in another language and voila!
Related
I'm developing a DLL and I want to log some data it generates.
I wanted to use "Log4Net", but I found the problem that in a DLL I don't have an "App.config" file where I can write the XML code, so I don't know how to implement this (I'm new in this matters).
I read about "Singleton" but I saw it's better to avoid it since it has it's issues (i.e hide some visibility of the code, problems with unit tests, ...).
So my question is: How and what is the best way to create a log file for the data generated by my DLL?
A DLL - a class library - should never be logging by itself. Even the ones that are there for output - like the one containing Console or even logger code - should never decide to write their own logfile. Logging work - all output work - that is not controllable or even fully controlled by the programmer using your DLL, is just going to be vexing behavior. And you should never write something with Vexing behavior.
Logging is the job of the person using your code, not of your code. If you are writing a Library or really anything else that usually has no output (like a Windows Service), it is customary to have a wrapper project for debugging and testing.
If it is important enough it warants an Exception. If it is not important enough for a Exception - it is propably not important enough at all. It is a daunting challenge to write good Exception handling, nevermind good Exception throwing code. But there are two articles on the mater that I link very often. And I really think would help you get you on the right paths:
https://blogs.msdn.microsoft.com/ericlippert/2008/09/10/vexing-exceptions/
https://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET
They really helped me get a handle on it. And thus far they helped countless others. And their ideas are not even tied to .NET only.
The config file will be connected in running module.
It will be in exe file if it's a console application,
or in web.config in case of web application.
To log the application flow in the DLL,
Just create a Class that create and access the log text file.
In that class, declare the object LoggingClass loggingObject; and then use this instance to access the log file.
In creating object for it, you can use,
public static LoggingClass createOrGetObject()
{
return (loggingObject == null)? new LoggingClass() : loggingObject;
}
Now, just you can call this method to get the same instance that access the log file to write the log.
In this example, Log4Net is not used but works fine for logging.
You don't say who you expect to use your dll.
If it will be used by lots of other people and if the logging is useful to them, then may not want to be forced to use log4net or this may cause problems if they want to use a different version of log4net than you are using.
I have seen several dlls which use Common.Logging to avoid this issue which allows the consumers to use whichever logging package they want.
Having said that, see Configure log4net logging in dll for another possible solution.
I am building a multi-language MVC application and have a series of resource files with translated strings for messages that will be displayed to the user.
Is there any way of ensuring that any resource files added in the future have all required keys and are spelled correctly?
As an analogy, if the resource file was a regular class, you could provide an interface to ensure that all required method and properties were present in the implementing class. Is there a similar concept for resource files?
I've been unable to find a supported way to enforce an explicit contract upon a .resx file. Since your goal is ultimately to catch implementation errors before they show up at runtime (and compile time checking isn't possible), I recommend falling back to static code analysis. Luckily, .NET makes this trivially easy:
Use the System.Resources.ResXResourceReader class to read the contents of the resx files to be validated.
Implement a test that asserts against all required keys in the "contract" you'd like to enforce on the resx.
Test should run as part of an existing test suite, and failure will warn a developer of the implicit contract before encountering the problem at runtime.
Since your resource files will exist in a known location, you can trivially ensure that the tests run against all resx files in that directory. In this way, you don't even need to update the test when new resource files are added, only if the contract changes.
I've used a similar approach to help with maintenance of stored procedure names kept in (an extensive number of) resx files. Since the resource files are spread across dozens of projects, manual maintenance is tedious and error-prone -- in other words, it doesn't get done. The static code analysis approach has yielded few downsides, and I think it would work well in your case as well.
Landing page for resource files on MSDN
ResXResourceReader on MSDN
System.Resources.ResXResourceReader requires a reference to System.Windows.Forms. It's available on both .NET and Mono.
I wrote a class library in C# that uses a external XML file to store some data. I use this data (encoded rules) directly in the class library to do some substitutions within a text parser. The rules within the XML:
<rule>
<word>h e l l o</word>
<sub>Hello</sub>
</rule>
When I share the lib, I also have to share the XML. This is a bug source, at least for me ;) My question: is there any common way to solve such issues? Should I use app.config instead?
Thanks for any hint and best regards!
Why not embed the XML within the dll?
As with every external configuration data i can be changed or missing. So your application (or library) has to deal with such circumstances.
This means:
For every missing value you have a default value (should be declared in your documentation)
Check every value for correctness (type, range, etc.) (All input is evil!)
Blame user for invalid config files (error message, etc)
Implement and document behaviour in error case (abort, crash, use default value, etc)
So it doesn't matter which way to go, cause it is a user configuration (which means it can be changed by the user) and so you have to check those entries.
Create the XML file with default settings/values if it doesn´t exist.
I'm writing an XML code editor and I want to display syntax errors in the user interface. Because my code editor is strongly constrained to a particular problem domain and audience, I want to rewrite certain XMLException messages to be more meaningful for users. For instance, an exception message like this:
'"' is an unexpected token. The
expected token is '='. Line 30,
position 35
.. is very technical and not very informative to my audience. Instead, I'd like to rewrite it and other messages to something else. For completeness' sake that means I need to build up a dictionary of existing messages mapped to the new message I would like to display instead. To accomplish that I'm going to need a list of all possible messages XMLException can contain.
Is there such a list somewhere? Or can I find out the possible messages through inspection of objects in C#?
Edit: specifically, I am using XmlDocument.LoadXml to parse a string into an XmlDocument, and that method throws an XmlException when there are syntax errors. So specifically, my question is where I can find a list of messages applied to XmlException by XmlDocument.LoadXml. The discussion about there potentially being a limitless variation of actual strings in the Message property of XmlException is moot.
Edit 2: More specifically, I'm not looking for advice as to whether I should be attempting this; I'm just looking for any clues to a way to obtain the various messages. Ben's answer is a step in the right direction. Does anyone know of another way?
Technically there is no such thing, any class that throws an XmlException can set the message to any string. Really it depends on which classes you are using, and how they handle exceptions. It is perfectly possible you may be using a class that includes context specific information in the message, e.g. info about some xml node or attribute that is malformed. In that case the number of unqiue message strings could be infinite depending on the XML that was being processed. It is equally possible that a particular class does not work in this way and has a finite number of messages that occur under specific circumstances. Perhaps a better aproach would be to use try/catch blocks in specific parts of your code, where you understand the processing that is taking place and provide more generic error messages based on what is happening. E.g. in your example you could simply look at the line and character number and produce an error along the lines of "Error processing xml file LineX CharacterY" or even something as general as "error processing file".
Edit:
Further to your edit i think you will have trouble doing what you require. Essentially you are trying to change a text string to another text string based on certain keywords that may be in the string. This is likely to be messy and inconsistent. If you really want to do it i would advise using something like Redgate .net Reflector to reflect out the loadXML method and dig through the code to see how it handles different kinds of syntax errors in the XML and what kind of messages it generates based on what kind of errors it finds. This is likely to be time consuming and dificult. If you want to hide the technical errors but still provide useful info to the user then i would still recomend ignoring the error message and simply pointing the user to the location of the problem in the file.
Just my opinion, but ... spelunking the error messages and altering them before displaying them to the user seems like a really misguided idea.
First, The messages are different for each international language. Even if you could collect them for English, and you're willing to pay the cost, they'll be different for other languages.
Second, even if you are dealing with a single language, there's no way to be sure that an external package hasn't injected a novel XmlException into the scope of LoadXml.
Last, the list of messages is not stable. It may change from release to release.
A better idea is to just emit an appropriate message from your own app, and optionally display -- maybe upon demand -- the original error message contained in the XmlException.
When throwing custom exceptions or issuing messages to the end user, one could use hard-coded the strings (including string constants), use resource-only assemblies or get strings from a table in a database.
I would like my application to be able to switch to a different language easily without having to recompile. While storing the string resources in a assembly or database would achieve this purpose, it adds to the complexity of program logic which in turn adds to the cost of the product.
My question is: what is the best way to go with the objective in mind without ignoring the cost that comes with each option? If you have a practice that is better than what's been listed, I'd love to hear it.
Technologies:
OS: Windows family
Platform: .NET Frame 2 and up
Language: C#
Database: MS SQL 2005 and up
Thanks guys!
Cullen
Use resources:
How does this add more complexity to the program logic?
try
{
//do something with System.Net.Mail with invalid email..
}
catch (FormatException fex)
{
throw new Exception(Resources.ErrorMsg.Invalid_Email, fex);
}
Edit
In VS2008 when you create a resource, you can define if its internal or public. So assume we set it to public, in an assembly called ClassLibrary1, we can access a property like:
ClassLibrary1.Properties.Resources.InvalidError
Where InvalidError is the name of the error. Again I don't think this adds any compelxity to the logic.
.NET already supports multiple resources for multiple cultures using a naming convention:
<default resource file name>.<culture>.resx
Essentially as Josh pointed out VS2008 creates a nice type safe wrapper to access these resources.
However the VS UI exposes the bear minimum of what you can do.
If you create a new Resource File called exactly the same as the default, however add the culture info before the resx. (NOTE: You will need to create it somewhere else then copy it into the magic Properties folder.)
Then your application will if you have applied the culture to the thread accessing the resource pull the correct string from the specific resources.
For example:
// Using the default culture
string s = Resources.Error1Msg;
Thread.CurrentThread.CurrentUICulture = new CultureInfo("es-CO");
// Using the specific culture specified as above:
s = Resources.Error1Msg;
If you need to parameterize you message, use string.Format to parameterize the output.
One word of caution is try to architect your application layers in such a way that your exceptions carry a rich payload (to describe the error), instead of relying on just text.
That way your presentation layer can present the best UI experience which might utilize the payload.
HTH
Philip