Standarised Validation and Error checking C# - c#

I am currently developing a project which handles a lot of types of inputs which have constraints like a double being between 0 and 1. I am thinking of validating this input in a standardised way by using a class which I would call to validate the input and if the input was wrong would throw out a result to a log file or throw an exception.
tl;dr : Is there a good method to standardise validation across a program which uses a log file.
Example:
public void AddTimes(double time1, double time2)
{
if (time1 < 0)
{
ErrorManager.Validation_MustBeNonNegative(ErrorManager.GetName(new { time1 }), time1.ToString());
}
else if (time2 <= 0)
{
ErrorManager.Validation_MustBeNonNegativeNonZero(ErrorManager.GetName(new { time1 }), time2.ToString());
}
}

You can use log4net to do the logging from your custom method. Configuring and logging to log4net is a well documented topic on SO and so you should refine your question and search again.
To validate your value, you need to have a way of expressing the valid range. Microsoft includes some range checking features in it's frameworks, but you can easily roll your own:
public static void AssertTimesAreValid(double time1, double time2)
{
if (time1 < 0)
{
ErrorManager.Validation_MustBeNonNegative(ErrorManager.GetName(new { time1 }), time1.ToString());
throw new ArgumentException("Times are not far enough apart.");
}
else if (time2 <= 0)
{
ErrorManager.Validation_MustBeNonNegativeNonZero(ErrorManager.GetName(new { time1 }), time2.ToString());
throw new ArgumentException("Times are not far enough apart.");
}
}
public void AddTimes(double time1, double time2)
{
AssertTimesAreValid(time1, time2)
// Do your work now
}
Your ErrorManager will need to do the logging.

Related

What is proper way to save data from file to object C#

what is proper way to save all lines from text file to objects. I have .txt file something like this
0001Marcus Aurelius 20021122160 21311
0002William Shakespeare 19940822332 11092
0003Albert Camus 20010715180 01232
From this file I know position of each data that is written in file, and all data are formatted.
Line number is from 0 to 3
Book author is from 4 to 30
Publish date is from 31 to 37
Page num. is from 38 to 43
Book code is from 44 to 49
I made class Data which holds information about start, end position, value, error.
Then I made class Line that holds list of type Data, and list that holds all error founded from some line. After load data from line to object Data I loop through lineError and add errors from all line to list, because I need to save errors from each line to database.
My question is this proper way to save data from file to object and after processing same data saving to database, advice for some better approach?
public class Data
{
public int startPosition = 0;
public int endPosition = 0;
public object value = null;
public string fieldName = "";
public Error error = null;
public Data(int start, int end, string name)
{
this.startPosition = start;
this.endPosition = end;
this.fieldName = name;
}
public void SetValueFromLine(string line)
{
string valueFromLine = line.Substring(this.startPosition, this.endPosition - this.startPosition);
// if else statment that checks validity of data (lenght, empty value)
this.value = valueFromLine;
}
}
public class Line
{
public List<Data> lineData = new List<Data>();
public List<Error> lineError = new List<Error>();
public Line()
{
AddObjectDataToList();
}
public void AddObjectDataToList()
{
lineData.Add(new Data(0, 3, "lineNumber"));
lineData.Add(new Data(4, 30, "bookAuthor"));
lineData.Add(new Data(31, 37, "publishData"));
lineData.Add(new Data(38, 43, "pageNumber"));
lineData.Add(new Data(44, 49, "bookCode"));
}
public void LoadLineDataToObjects(string line)
{
foreach(Data s in lineData)
{
s.SetValueFromLine(line);
}
}
public void GetAllErrorFromData()
{
foreach (Data s in lineData)
{
if(s.error != null)
{
lineError.Add(s.error);
}
}
}
}
public class File
{
public string fileName;
public List<Line> lines = new List<Line>();
}
I assume that the focus is on using OOP. I also assume that parsing is a secondary task and I will not consider options for its implementation.
First of all, it is necessary to determine the main acting object. Strange as it may seem, this is not a Book, but the string itself (e.g. DataLine). Initially, I wanted to create a Book from a string (through a separate constructor), but that would be a mistake.
What actions should be able to perform DataLine? - In fact, only one - process. I see two acceptable options for this method:
process returns Book or throws exceptions. (Book process())
process returns nothing, but interacts with another object. (void process(IResults result))
The first option has the following drawbacks:
It is difficult to test (although this applies to the second option). All validation is hidden inside DataLine.
It is impossible/difficult to return a few errors.
The program is aimed at working with incorrect data, so expected exceptions are often generated. This violates the ideology of exceptions. Also, there are small fears of slowing performance.
The second option is devoid of the last two drawbacks. IResults can contain methodserror(...), to return several errors, and success(Book book).
The testability of the process method can be significantly improved by adding IValidator. This object can be passed as a parameter to the DataLine constructor, but this is not entirely correct. First, this unnecessary expense of memory because it will not give us tangible benefits. Secondly, this does not correspond to the essence of the DataLine class. DataLine represents only a line that can be processed in one particular way. Thus, a good solution is the void process (IValidator validator, IResults result).
Summarize the above (may contain syntax errors):
interface IResults {
void error (string message);
void success (Book book);
}
interface IValidator {
// just example
bool checkBookCode (string bookCode);
}
class DataLine {
private readonly string _rawData;
// constructor
/////////////////
public void process (IValidator validator, IResults result) {
// parse _rawData
bool isValid = true; // just example! maybe better to add IResults.hasErrors ()
if (! validator.checkBookCode (bookCode)) {
result.error("Bad book code");
isValid = false;
}
if (isValid) {
result.success(new Book (...));
// or even result.success (...); to avoid cohesion (coupling?) with the Book
}
}
}
The next step is to create a model of the file with the lines. Here again there are many options and nuances, but I would like to pay attention to IEnumerable<DataLine>. Ideally, we need to create a DataLines class that will support IEnumerable<DataLine> and load from a file or from IEnumerable<string>. However, this approach is relatively complex and redundant, it makes sense only in large projects. A much simpler version:
interface DataLinesProvider {
IEnumerable <DataLine> Lines ();
}
class DataLinesFile implements DataLinesProvider {
private readonly string _fileName;
// constructor
////////////////////
IEnumerable <DataLine> Lines () {
// not sure that it's right
return File
. ReadAllLines (_fileName)
.Select (x => new DataLine (x));
}
}
You can infinitely improve the code, introduce new and new abstractions, but here you must start from common sense and a specific problem.
P. S. sorry for "strange" English. Google not always correctly translate such complex topics.

Can I generate the compile date in my C# code to determine the expiry for a demo version?

I am creating a demonstration version of a C# program and I wish it to expire after a month.
// DEMO - Check date
DateTime expires = new DateTime(2016, 3, 16);
expires.AddMonths(2);
var diff = expires.Subtract(DateTime.Now);
if (diff.Days < 0)
{
MessageBox.Show("Demonstration expired.");
return;
}
I am wanting to have the date the compile instead of the hard coded new DateTime(2016, 3, 16);
Is there a compiler directive to give me the current date? Or am I aproaching this the wrong way?
But pre-processor directives are used during compile-time.
That expiration should be implemented using executable code. The issue here is you can hardcode it and hide it as much as possible, but it avid developers can find it and replace the intermediate language and generate a new assembly without the expiration. Actually, there're many other cases where an user can by-pass the whole expiration...
It seems like your best bet should be creating some kind of unique key, store it in your app and check if the whole key is still valid over the wire connecting to some licensing service developed by you.
An alternative solution to hard-coding a date that also offers some flexibility and extensibility could be to host a license file on a web server. For my sample, I used github. Create a well-known file for the application (possibly one for demo and a new one for beta1, etc.). At startup, and possibly periodically, read the file and parse it to determine applicability, timeouts, disable/enable features (like activating a custom warning message), etc.
Now you can ship your demo, put the expire date in the file, change it if needed, etc. This is not the most elegant nor secure solution, but for many use cases for a demo/beta, this might be enough to serve its intended purpose.
Below is a working mock-up of how this might look (omitted error checking and proper cleanup for brevity):
public class LicenseInfo
{
public string Info1 { get; private set; }
public bool IsValid
{
get
{
// todo, add logic here
return true;
}
}
public bool ParseLicense(string data)
{
bool ret = false;
if (data != null)
{
// todo, parse data and set status/attributes/etc
Info1 = data;
ret = true;
}
return ret;
}
}
// could make a static class...
public class License
{
public LicenseInfo GetLicenseInfo()
{
var license = new LicenseInfo();
// todo: create whatever schema you want.
// filename hard-coded per app/version/etc.
// file could contain text/json/etc.
// easy to manage, update, etc.
// extensible.
var uri = "https://raw.githubusercontent.com/korygill/Demo-License/master/StackOverflow-Demo-License.txt";
var request = (HttpWebRequest)HttpWebRequest.Create(uri);
var response = request.GetResponse();
var data = new StreamReader(response.GetResponseStream()).ReadToEnd();
license.ParseLicense(data);
return license;
}
}
class Program
{
static void Main(string[] args)
{
// check if our license if valid
var license = new License();
var licenseInfo = license.GetLicenseInfo();
if (!licenseInfo.IsValid)
{
Console.WriteLine("Sorry...license expired.");
Environment.Exit(1);
}
Console.WriteLine("You have a valid license.");
Console.WriteLine($"{licenseInfo.Info1}");
}
}

Correct work with exceptions

For example, I have the following method:
public void MeetingNoteSave(int MeetingID, string note, bool IsInviter, string Username)
{
meeting = Get<Meeting>(p => p.MeetingID == MeetingID && p.UserInviter.aspnet_User.UserName == Username);
MeetingNoteSaveCheckings(meeting, MeetingID);
// some actions here
}
void MeetingNoteSaveCheckings(Meeting meeting, int MeetingID)
{
DateTime currentDateWithTime = DateTime.Now;
if (meeting == null)
{
throw new Exception("Meeting does not exist. MeetingID=" + MeetingID);
}
DateTime meetingTime = meeting.MeetingTime.Day.AddHours(meeting.MeetingTime.Hour).AddMinutes(meeting.MeetingTime.Minute);
if (meetingTime > currentDateWithTime)
{
throw new Exception("Meeting is future. MeetingID=" + MeetingID + ". Meeting time = '" + meetingTime + "', Current time='" + currentDateWithTime + "'");
}
}
so, method can throw 2 exceptions - when meeting not exists with such parameters at all or when time of meeting more than current time (should be past or current).
Now, I'm writting Unit Tests. Simple method:
[TestMethod]
public void MeetingNoteSave()
{
_repository.MeetingNoteSave(1, "My note", true, "xxx#xxx.com");
}
Of course, call unit test will be fail with some parameters. I want to catch these cases, so, test should be success. I can do by 2 ways. First is simple, but a little dirty:
try
{
_repository.MeetingNoteSave(1, "My note", true, "xxx#xxx.com");
}
catch(Exception ex)
{
if (ex.Message.IndexOf("Meeting does not exist")>=0)
{
// some actions
}
if (ex.Message.IndexOf("Meeting is future")>=0)
{
// some actions
}
}
so, test will be success with incorrect input parameters (so, unit test can be used to test method with incorrect parameters), but fail with encountered errors. Good.
Other way - create special dummy exceptions like MeetingNullException and MeetingFutureException
public class MeetingNullException : Exception
{
}
public class MeetingFutureException : Exception
{
}
throw them and catch them. More correctly, but much more code. Dummy code.
Which way is more correctly?
Neither, they're both flawed. Your second approach is in the right direction though: you should avoid throwing general exceptions of type Exception; specific subclasses are much more expressive.
What you have to do in your tests then is use the [ExpectedException] attribute which will make them look like this:
[TestMethod]
[ExpectedException(typeof(MeetingNullException))]
public void MeetingNoteSave_WithNotExistingMeeting()
{
_repository.MeetingNoteSave(1, "My note", true, "xxx#xxx.com");
}
[TestMethod]
[ExpectedException(typeof(MeetingFutureException ))]
public void MeetingNoteSave_WithFutureDate()
{
_repository.MeetingNoteSave(1, "My note", true, "xxx#xxx.com");
}
Make sure you only have one test for each possible flow of your program: 2 exceptions means 2 tests. Personally I might avoid creating the specific subclasses and just use ArgumentException but that's up to you to decide. If you have expressive test names and the code is sufficiently self documenting, you'll know what argument is being referred to anyway.

Design pattern for dynamic C# object

I have a queue that processes objects in a while loop. They are added asynchronously somewhere.. like this:
myqueue.pushback(String value);
And they are processed like this:
while(true)
{
String path = queue.pop();
if(process(path))
{
Console.WriteLine("Good!");
}
else
{
queue.pushback(path);
}
}
Now, the thing is that I'd like to modify this to support a TTL-like (time to live) flag, so the file path would be added o more than n times.
How could I do this, while keeping the bool process(String path) function signature? I don't want to modify that.
I thought about holding a map, or a list that counts how many times the process function returned false for a path and drop the path from the list at the n-th return of false. I wonder how can this be done more dynamically, and preferably I'd like the TTL to automatically decrement itself at each new addition to the process. I hope I am not talking trash.
Maybe using something like this
class JobData
{
public string path;
public short ttl;
public static implicit operator String(JobData jobData) {jobData.ttl--; return jobData.path;}
}
I like the idea of a JobData class, but there's already an answer demonstrating that, and the fact that you're working with file paths give you another possible advantage. Certain characters are not valid in file paths, and so you could choose one to use as a delimiter. The advantage here is that the queue type remains a string, and so you would not have to modify any of your existing asynchronous code. You can see a list of reserved path characters here:
http://en.wikipedia.org/wiki/Filename#Reserved_characters_and_words
For our purposes, I'll use the percent (%) character. Then you can modify your code as follows, and nothing else needs to change:
const int startingTTL = 100;
const string delimiter = "%";
while(true)
{
String[] path = queue.pop().Split(delimiter.ToCharArray());
int ttl = path.Length > 1?--int.Parse(path[1]):startingTTL;
if(process(path[0]))
{
Console.WriteLine("Good!");
}
else if (ttl > 0)
{
queue.pushback(string.Format("{0}{1}{2}", path[0], delimiter,ttl));
}
else
{
Console.WriteLine("TTL expired for path: {0}" path[0]);
}
}
Again, from a pure architecture standpoint, a class with two properties is a better design... but from a practical standpoint, YAGNI: this option means you can avoid going back and changing other asynchronous code that pushes into the queue. That code still only needs to know about the strings, and will work with this unmodified.
One more thing. I want to point out that this is a fairly tight loop, prone to running away with a cpu core. Additionally, if this is the .Net queue type and your tight loop gets ahead of your asynchronous produces to empty the queue, you'll throw an exception, which would break out of the while(true) block. You can solve both issues with code like this:
while(true)
{
try
{
String[] path = queue.pop().Split(delimiter.ToCharArray());
int ttl = path.Length > 1?--int.Parse(path[1]):startingTTL;
if(process(path[0]))
{
Console.WriteLine("Good!");
}
else if (ttl > 0)
{
queue.pushback(string.Format("{0}{1}{2}", path[0], delimiter,ttl));
}
else
{
Console.WriteLine("TTL expired for path: {0}" path[0]);
}
}
catch(InvalidOperationException ex)
{
//Queue.Dequeue throws InvalidOperation if the queue is empty... sleep for a bit before trying again
Thread.Sleep(100);
}
}
If the constraint is that bool process(String path) cannot be touched/changed then put the functionality into myqueue. You can keep its public signatures of void pushback(string path) and string pop(), but internally you can track your TTL. You can either wrap the string paths in a JobData-like class that gets added to the internal queue, or you can have a secondary Dictionary keyed by path. Perhaps even something as simple as saving the last poped path and if the subsequent push is the same path you can assume it was a rejected/failed item. Also, in your pop method you can even discard a path that has been rejected too many time and internally fetch the next path so the calling code is blissfully unaware of the issue.
You could abstract/encapsulate the functionality of the "job manager". Hide the queue and implementation from the caller so you can do whatever you want without the callers caring. Something like this:
public static class JobManager
{
private static Queue<JobData> _queue;
static JobManager() { Task.Factory.StartNew(() => { StartProcessing(); }); }
public static void AddJob(string value)
{
//TODO: validate
_queue.Enqueue(new JobData(value));
}
private static StartProcessing()
{
while (true)
{
if (_queue.Count > 0)
{
JobData data = _queue.Dequeue();
if (!process(data.Path))
{
data.TTL--;
if (data.TTL > 0)
_queue.Enqueue(data);
}
}
else
{
Thread.Sleep(1000);
}
}
}
private class JobData
{
public string Path { get; set; }
public short TTL { get; set; }
public JobData(string value)
{
this.Path = value;
this.TTL = DEFAULT_TTL;
}
}
}
Then your processing loop can handle the TTL value.
Edit - Added a simple processing loop. This code isn't thread safe, but should hopefully give you an idea.

User verification code, in a method/s

Evening guys,
This may seem like a stupid question but im having some issues figuring out where i should be placing my user input verification checks. I have checks, for the following:
file exists
Correct extension
Access to the file
Input in 2 NumericUpDown controls
One numericUpDown is always greater than the other.
Assignment to static properties.
Im assuming each one of these should at least be a single method but i then have a single method which has a large number of lines which solely check the result of the method calls to the list above. ie
public void VerifyData()
{
if(VerifyNumber1OnTheList != true)
{
LogError("The file specified is incorrect")
return;
}
if(VerifyNumber2OnTheList != ......
Any suggestions on how i should actually be laying this out would be appreciated.
Thanks
Putting a series of validation methods is ok.
This is user input, so you're doing defensive programming here, not looking for exceptional errors. It seems like you'd want to know why the user input is bad. If so, a simple approach is to use a collecting object to visit each validation method
public void VerifyData(ValidationErrors errors)
{
ValidateFileExists(errors);
ValidateExtension(errors);
ValidateFileAccess(errors);
...
}
private void ValidateFileExists(ValidationErrors errors)
{
if(!File.Exists...)
{
errors.Add("File does not exists.");
}
}
public void CallingMethod(UserInput input)
{
_dataToVerify = input;
var errors = new ValidationErrors();
VerifyData(errors);
if(errors.Count > 0)
ShowErrors(errors);
else
ShowSuccess();
}
I just put the data in an instance variable for purposes of simplicity, you could pass that into your validation method. This approach is simple but allows you to tell the user something about the input and how to correct it.
All right here is a quick sample I wrote up for you. Architecture obviously is your choice here. Modify as needed. I believe this should be a great jumping off point for you.
Cheers
Matt
using System.Collections.Generic;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//This would simulate the event handler that calls your validation event
List<string> errorList = Validation.VerifyData();
if (errorList.Count != 0)
{
ErrorHandler.HandleError(errorList);
return;
}
//Do stuff if validation actually passed here.
}
}
public static class Validation
{
public static List<string> VerifyData()
{
List<string> errorList = new List<string>();
//File exists
if (true)
errorList.Add("File doesn't exist.");
//File has correct extension
if (true)
errorList.Add("File doesn't exist.");
//Has access to the file
if (true)
errorList.Add("File doesn't exist.");
//INput in 2 NumericUpDownControls
if (true)
errorList.Add("File doesn't exist.");
//One NumericUpDown is always greater than the other
if (true)
errorList.Add("File doesn't exist.");
//Assignment to static properties
if (true)
errorList.Add("File doesn't exist.");
return errorList;
}
}
public static class ErrorHandler
{
public static void HandleError(List<string> errorMessageList )
{
//Display your message here. This could return a dialog result as well for further processing.
}
}
}
Your method above seems like a perfectly fine way of laying out your code.
My only change would be in how you handle your checking. Use well-named methods rather than booleans during your check:
public void VerifyData()
{
if(FileExists())
{
LogError("The file specified is incorrect")
return;
}
if(CorrectExtension())

Categories