Backward Engineering a File Parsing MicroORM Solution
I love my work!
I’m given application code I’ve never seen and in a language I don’t code in often enough and asked to figure it out.
Luckily, I have access to business analysts and a DBAs to get details about the business processes and databases the code is related to.
From code and info resources, create working test environment and get familiar enough with application code and databases to have new updates in to production in 2-3 weeks.
No pressure, right?
I was fairly successful today and here are some of the resources that used to solve problems I encountered.
Massive MicroORM
It’s a small MicroORM based on the Expando or dynamic type and allows you to work with your database with almost no effort. The design is based on the idea that the code provided to you in this repository is a start: you get up and running in no-time and from there edit and alter it as you see fit.
Specific to C# MVC, Razor Views are code snippets with special syntax made up of C# code and HTML/CSS. The C# logic can interact with and output HTML and CSS elements/attributes dynamically.
With Razor Views, we use the @ symbol to switch between C# code and HTML.
Video: Razor Views in C# MVC
A simple example of printing numbers from 1 to 10 using Razor.
Sample Code
@for {int i = 1; i <=10; i++)
{
<b>@i</b>
}
The Output would be: 1 2 3 4 5 6 7 8 9 10 Inside the brackets, Razor sees the <b>@i</b> and knows to render the C# variable i when its proceeded with an @ character then Razor sees the angle brackets and switches back in to HTML parsing mode.
If we didn’t want to use HTML we could change the <b> tag to <text> and output would just be text without the HTML.
The most important thing to understand and remember about Razor Views is the context switching in the parser is based on detection of specific characters.
@ character starts the C# parser but HTML & text won’t parse until Razor see a tag wrapped in angle brackets. We are just switching back and forth between to parsing modes. Make sense?
The loop is C# code but the output is HTML. In ASP Classic and .Net, the Response Object would handle the HTML output to the browser from inside the loop.
Here are two more examples to help us cement the idea in our brains.
1. A simple date:
@{
int day = 24;
int month = 08;
int year = 2020;
}
Date is @day-@month-@year
Output = Date is 24-08-2020
2. Loop thru images in folder
@for (int i = 1; i <= 5; i++)
{
<img src="~/Images/@(i).png" />
}
Notice how in the sample above, we put the variable inside the parenthesis. Why, when we didn’t do this for the date example above?
Because if we don’t C# will try and read i. and an object with a property so we have to wrap it in parenthesis. This tell the Razor syntax that we are just trying to concatenate the values.
Razor View Code Blocks
In Razor Views we define code blocks using @{}.
@{
int SumOfEvenNumbers = 0;
int SumOfOddNumbers = 0;
for(int i=1; i<=10; i++)
{
if(i %2==0)
{
SumOfEvenNumbers = SumOfEvenNumber + 1;
}
else
{
SumOfOddNumbers = SumOfOddNumbers + 1;
}
}
}
<h3>Sum of Even Numbers = @SumOfEvenNumbers</h3>
<h3>Sum of Odd Numbers = @SumOfOddNumbers</h3>
Razor View Comments
Razor View multi-line code comments are very similar to JavaScript and CSS that use the asterisk and forward slash, /* */, to wrap comments.
Razor View multi-line comments use ampersand and asterisk in same way. @* to start a multi-line comment and *@ to end it. (See code example below)
What’s in the Razor View Example Below?
H2 tag class name is dynamically selected based on logic, if Model.Customers.Count is greater than 5 then change the CSS class of the H2 element to “popular”.
Also, inside the <ul> tags, Razor View code loops through the list of customers and outputs the name.
Sample C# Code Example:
@model Vidly.ViewModels.RandomMovieViewModel
@{
ViewBag.Title = "Random";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@*
This is a comment
on multiple lines
*@
@{
var className = Model.Customers.Count > 5? "popular": null;
}
<h2 class="@className">@Model.Movie.Name</h2>
@if (Model.Customers.Count == 0)
{
<text>No one has rented the movie before.</text>
}
else
{
<ul>
@foreach (var cusomter in Model.Customers)
{
<li>@cusomter.Name</li>
}
</ul>
}
A “For Loop” executes a block of code a specific number of times or while a specified condition is true.
PHP For Loop
for (init; condition; increment)
{
code to be executed;
}
php fOR lOOP PARAMETERS
init: Mostly used to set a counter (but can be any code to be executed once at the beginning of the loop)
condition: Evaluated for each loop iteration. If it evaluates to TRUE, the loop continues. If it evaluates to FALSE, the loop ends.
increment: Mostly used to increment a counter (but can be any code to be executed at the end of the iteration)
Note: The init and increment parameters above can be empty or have multiple expressions (separated by commas). Example The example below defines a loop that starts with i=1. The loop will continue to run as long as the variable i is less than, or equal to 5. The variable i will increase by 1 each time the loop runs:
PHP For Loop Example Code
<?php
for ($i=1; $i<=5; $i++)
{
echo("The number is " . $i . "<br>");
}
?>
Classic ASP For Loop Example Code
<%
For i = 1 to 5
Response.Write("The number is " & i & "<br>")
Next
%>
JavaScript For Loop Example
<%
For i = 1 to 5
Response.Write("The number is " & i & "<br>")
Next
%>
C# For Loop Example
for (int i = 0; i < 5; i++)
{
Console.WriteLine(i);
}
Python For Loop Example
states = ["Alaska", "Alabama", "Arkansas"]
for x in states:
print(x)
if x == "Alabama":
break
When creating a custom model/object for your C# project and try to use it to build a List that made of that custom object type, you’ll be greeted with an error.
C# Error CS0246: The type or namespace name ‘List<>’ could not be found
Error: The type or namespace name ‘List’ could not be found (are you missing a using directive or an assembly reference?)
Error seen when creating a List of custom objects without using including the using generics statement.
The missing element is a reference to using System.Collections.Generic
Code Example
using OfficeOpenXml;
using System;
using System.IO;
using System.Collections.Generic;
namespace ExcelDemo
{
class Program
{
static void Main(string[] args)
{
//Set the EPPlus license context to nonCommercial so we can play with it :-)
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
var file = new FileInfo(@"c:\scripts\demo.xlsx");
}
static List<PersonModel> GetSetupData()
{
List<PersonModel> output = new()
{
new() { Id = 1, FirstName= "rick", LastName = "cable" },
new() { Id = 2, FirstName="bob",LastName= "marley" },
new() { Id = 3, FirstName="willie",LastName= "nelson" }
};
return output;
}
}
}
References
As always, give credit where credit is due. In this case, a big thank you to David Morton for the post on the Microsoft Visual Studio forums.
Below is Corey’s Video. Watch it, then if you’re still interested. My personal training notes will be shared below. It might help you if you’re feeling stuck or want to cement an idea in your own mind.
The xmas tree project was a good idea. It really makes you think. I think this project could have been a little more fun for me if I had a little more time but my schedule just won’t allow it. I don’t see myself coming back to often to update this code but if others want to sent me some other samples I may post them later. So here it goes….
Screenshot of command line window.
C# ASCII XMas Tree Code Sample
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//create the main array
int[] myArray = new int[] { 1, 3, 5, 7, 9 };
//The outside foreach loop to loop throught the array
foreach (int intLoop in myArray)
{
//creates the spaces, takes the array number minus 1 then divide by 2
//this gives you the amount of spaces needed for each level of the tree
for (int iSpace = 0; iSpace < ((myArray[4]-intLoop)/2); iSpace++)
{
System.Console.Write(" ");
}
//middle loop writes the asterisks "*" the full amount of current array[]
for (int i = 0;i < intLoop; i++)
{
System.Console.Write("*");
}
//creates the spaces, takes the array number minus 1 then divide by 2
//this gives you the amount of spaces needed for each level of the tree
for (int iSpace = 0; iSpace < ((myArray[4] - intLoop) / 2); iSpace++)
{
System.Console.Write(" ");
}
//creates new lines after all 3 loops run
System.Console.WriteLine("");
}
//nest this loop and do it 3 times
for (int iBase = 0; iBase < myArray[1]; iBase++)
{
// now make the base of the tree
for (int iSpaces = 0; iSpaces < myArray[1]; iSpaces++)
{
System.Console.Write(" ");
}
for (int iPipes = 0; iPipes < myArray[1]; iPipes++)
{
System.Console.Write("|");
}
// now make the base of the tree
for (int iSpaces = 0; iSpaces < myArray[1]; iSpaces++)
{
System.Console.Write(" ");
}
//creates new lines after all 3 loops run
System.Console.WriteLine("");
}
}
}
}