Sounds very formal...but it's not..I've made a couple of things in C# because I tried out Talking SOAP with C#. But that was different. I imported web-references and used whatever was built from "our" supplier...

But this was my first "proffesional" application. The purpose of the application was to filter out mails by date, and print out attachments by date, in two different formats. First page was a "cover-page", and the second was an attachment in  the filetype .pdf, that was X-pages of stickers, that could be taken out from the subject of the mail. The project started June'2019, as a curiosity from my side. First commit to GitHub was in September'2019, after the project was approved from my employer.

In short; this is what the application does:

  1. Connect to an Email-server(IMAP)
  2. Read mails in "INBOX" (root) (The subject-line contains information about a specific order, when to send, and how many copies of the attachment that should be printed)
  3. Filter mails by date from the subject-line in a specific format.
  4. Search subject-line for the number of copies to print
  5. print "accoringly" to (2) to (4)

To finish off this project in a "reasonable" amount of time there were mainly two things that I needed:

  1. API for connecting/reading emails from an Email-server
  2. API to view/print/handle PDF-documents

It's not really a problem to find anything if you pay for it. But this was a just something I did in my free time to "practice", so I was not interested in paying for anything. I tried some API's, through Visual Studio that I thought was free, but were actually just trial. A little bit frustrating one might say. But eventually I did find what I needed through a combination of searching the web and NuGet via VS.

  1. API for cennecting to an Email-server(IMAP): MailKit by jstedfast. Really nice. It's up to date. Even to this date when I'm writing.
  2. API for viewing and printing PDF-documents(probably the most difficult to find). PdfiumViewer (2017). Old API but it works for my use.

I must admit that I did alot of mistakes. Not really mistakes, but there were better solutions that was changed as my train of thought changed. The main problem(except for finding some API's) was to filter/search the mail-subject for the information that I needed. In the beginning I manually filtered all "text" that was expected in a certain order. An example of the string can be this: "Packingday 200519 - ORDER 12345 - New York - 25 pages". A template of this will be: "packingday(C) - ddMMyy(V) - order(C) abcde(V) - City(V) - xy(V) - pages(C)", where C is a constant string that is expected, and V is variable string.

This is not a difficult problem to solve. But sometimes these Emails had been forwarded or replied to from the originator, and the string ended up in the format "Fwd: Packingday - 220419 - etc". So I had to deal with the prefix "Fwd:". And later on "Re: ...." and even "Fwd: Re: Packag......"..etc..

Yeah. There were alot of special cases one might say...

The first time I had an actual "talk" with the 3rd party, I thought that the email was auto-generated so that the format of the subject would be constant. But it was not. The employees were actually just good at following orders. I forgot to ask..So the format would change from time to time, and at some point I actually found out that the emails were made from "humans" First commit to github(FilterSubject):

 /**
         * This function will try to filter out some of the most common variations of the subject, that has impact on the routine.
         * Problem arise if mail is forwarded or replied to and some senders adding messages in the subject-line. There's alot of variations,
         * so I'll just have to add them as they come.
         **/
        public List<String> FilterSubject(String str)
        {
            List<String> T = new List<String>();
            string[] table = str.Split(' ');

            string prevWord = null;
            foreach (string word in table)
            {
                if ((word.ToString() == "-") ||
                    (word.ToString().ToLower() == "fw:") || //forwarded message
                    (word.ToString().ToLower() == "re:") || //replied to message
                    (word.ToString() == ""))
                    continue;
                else
                {
                    if (prevWord != null)
                        if (prevWord.ToString().ToLower() == "ark") //someone is trying to add some kind of msg after the standard subject..we don't want it..break off.
                            break;
                    T.Add(word);
                    //keep track of previous word so we can look for certain placeholders
                    prevWord = word;
                }
            }
            return T;
        }

There was a lot of changes as time went, and I found out that I had to find a more generic solution. I had to think that the user will never be able to follow those exact instructions. Therefore, the construction of the funtion changed. We cannot rely on the fact that "humans" can do what is told at all times. :D.

To make things short: The above solution for FilterSubject was not the way to go!

So what I did, was to remove everything that is not important(That is: remove everything that can be expected to go wrong):
Remove everything before the text "Packingday" and remove everything after the term "Pages", and then search for number_of_pages(xy).

I'm going to make things VERY short when it comes to the problems mentioned earlier. I removed every line of code that was looking for "special cases" and implemented RegEx(Regular Expressions) into the code. I still had to remove everything before and after, but I also removed every character that could be a nuance. So if a subjectline looked like this, 
"Re: Fwd: Packingday 200519 - ORDER 12345 - New York - 25 pages -Please change your cloths and do not pee on the floor". 

it ended up like this before it was sent to the RegEx-function

"200519order12345newyork25"

In this case, only the first 6 digits and the last digits in the string are important. That is: extracting the date and number_of_pages - variable. The pattern is simple.

Why I ended up using the uft16 characters in the range [u0061-u10f8] is another story, which is also kind of interesting, but not important at this moment. In most cases you can use (w+). But not in this case. The current FilterSubject-function looks like this:

/// <summary>
 /// Mainly uses Regex to remove "noise" from the string and getting to the string values that count. 
/// </summary>
/// <returns>Mail-subject in a List of strings</returns>
public List<String> FilterSubject(String str)
{
            List<String> T = new List<String>();
            str = str.ToLower();
            var charsToRemove = new string[] { "-", " ", ",", ".","å", "ø", "æ" };
            foreach (var c in charsToRemove)
            {
                str = str.Replace(c, string.Empty);
            }
            int index = str.IndexOf("pakkedag");
            if (index >= 0)
            {
                str = str.Remove(0, index + "pakkedag".Length);//remove anything before "pakkedag" and "pakkedag"
            }
            index = str.IndexOf("ark");
            int ind;
            if ((ind = str.IndexOf("ark", index+3)) > 0)//look for a second occurence of "ark"
                index = ind;
            str = str.Remove(index);    //remove last instance of ark.
            //string pattern = @"(\d+)([\p{L}]+)(\d+)([\p{L}]+)(\d+)";
            //look for this string pattern: 'ddmmyy'"ordre"'order_number''order_city''no_of_copies'
            //                        where 'ddmmy', 'order_number', 'order_city', and 'no_of_copies' are variable, while "ordre" is static.
            string pattern = @"(\d+)([\u0061-\u10f8]+)(\d+)([\u0061-\u10f8]+)(\d+)";

            Match result = Regex.Match(str, pattern);
            //string test = 
            //if result is null, just a make a default
            if (!result.Success)//if the preg ex-expression fails just make a dummy: the date is probabl not the problem: get todays date and some default shit up, we don't want to fail at all.
            {
                pattern = @"(\d+)";//get the date.
                result = Regex.Match(str, pattern);
                T.Add(result.Groups[1].Value);
                T.Add("ordre"); //"ordre"
                T.Add("9999999"); //ordernumber
                T.Add("En eller annen plass: 10 copies"); //place
                T.Add("10"); //number of copies
            }
            else
            {
                T.Add(result.Groups[1].Value); //date 
                T.Add(result.Groups[2].Value); //"ordre"
                T.Add(result.Groups[3].Value); //ordernumber
                T.Add(result.Groups[4].Value); //place
                T.Add(result.Groups[5].Value); //number of copies
            }
            return T;
}

 

Well...anyway....these were internal problems, and I was supposed to talk about my first C# Application and how easy it is to use C# + .NET + WPF. It is actually...but there are always things that do not works as you suspect. Maybe the right term for me should of been "RTFM", but it was actually kind of fun. You "draw" your graphical interface, use the xaml to connect to functions in the code and bla bla. My configuration page ended up like this:

The point of this was that the user was supposed to choose a packing-day, and the application would find the right mails containing that date and print all that was needed to print. The main page looked like this(with an example):

For my first try, I don't think it's so bad. It did something usefull. In other words it was practical, and made operations more efficient. That's the main point.