An Update On My ASP.NET Core Project

My previous post reviewed over utilizing ASP.NET Core to create a Web API endpoint. In that post, I stated that there was nothing as of that writing that prevented me from continuing the usage of ASP.NET Core and .NET Core. However, as time went on, it was decided to use OData. This is where my roadblock appeared. As of the writing of this post, OData support does not currently exist for ASP.NET Core. I’ve got a separate project that didn’t make sense to use OData, so we’re going with ASP/.NET Core for that project. I’m pretty excited about that, considering all the benefits I’d talked about in my previous post.

For those unfamiliar, OData (Open Data Protocol) is a standard that defines how to build and utilize RESTful APIs. This standard is utilized in the .NET world via the Microsoft.Data.OData Nuget package, and can be utilized in an ASP.NET project using the Microsoft.AspNet.OData Nuget package (both described in more detail here). With OData, a client can specify what data they would like returned via a query string or other parameter. This in turn is translated into a specific query that only returns the specified dataset. This is very useful for minimizing data traffic and ensuring the client gets what they need.

For the project in question, we had a project returning JSON data with multiple fields and child objects. The total payload, including all objects and fields, was over 600MB. For a mobile experience, this would be unacceptable. There would also be multiple clients requesting different pieces of this data at any given time. While the clients could receive the full payload, and just ignore the fields and objects they don’t need, this is a waste of traffic. I could also create different endpoints for each need, but that could become difficult to manage over time as more needs arise. OData gave us the opportunity to specify a generic endpoint, and allow the client to decide what data they receive.

Looking into OData support for ASP/.NET Core, I found nothing. Looking deeper into the documentation, I found the RESTier project. At face value, this seems to be utilizing a more ASP.NET Core approach to creating an OData endpoint. However, it is also not supported for ASP/.NET Core at this time. Perhaps some time in the future, this may change.

In the meantime, I’ve pulled that project over to a full .NET 4.6.2 and AspNet.Mvc 5.2.3 project. That process was not too difficult; I created a new ASP.NET MVC project, added the existing files to it, switched IActionResults to IHttpActionResults, changed NoContent() results to StatusCode(HttpStatusCode.NoContent) results, and swapped out the Core Nuget packages for full .NET packages and using statements. Overall, it wasn’t too painful, even if I’d rather avoid doing it again.

Thanks for reading!

Advertisements

Getting Started With ASP.NET Core

Over the course of the last month, I’ve had the opportunity to learn, experiment with, and implement a Web API project utilizing ASP.NET Core. While this has been a very edifying experience, I found that the details of the newer technology is a bit spread out across multiple sources. My aim of this post is to compile those details, describe how I’ve started out, and explain what’s available and possible.

The first thing that I’d like to review over is probably my favorite part of .NET Core as a whole: portability. Do you want to use the rich features of Visual Studio to develop your application? Great, that still works as before. Would you rather just pull up Visual Studio Code or other simpler editor to make changes, big or small, and then build the code easily? The dotnet CLI gives you that capability, along with being able to create new projects, run tests, publish, and others. Do you want to develop .NET software, but don’t have an installation of Windows? No worries – .NET Core can be installed on Linux and Mac.

Next, we tackle one of the concerns that I’ve had – dependencies. Many well-used Nuget packages simply aren’t compatible with .NET Core. One would think this is a deal-breaker, but that’s not quite the case. Many third parties, such as the xUnit team, have created a .NET Core-specific Nuget package to be used in this instance. As of the writing of this blog post, I’m successfully using xUnit 2.2.0-beta5-build3474 and xUnit.Runner.VisualStudio 2.2.0-beta5-build1225 (the runner is used to run the tests in Visual Studio’s Test Runner). These versions can be found in the Nuget Package Manager by checking the box to ‘Include prerelease’ packages, which is next to the search box. As further proof of this point, I’m also using NLog.Web.AspNetCore version 4.3.1 for logging, and Swashbuckle.AspNetCore version 1.0.0-rc3 to bring in the visual documentation tool Swagger UI.

For anyone who has created an ASP.NET/Web API project in the past, you may find that some namespaces have either moved, or are not implemented at all. An example of this is when pulling settings from a configuration file. With the full version of .NET, one may likely use ConfigurationManager. However, as Jonathan Danylko succinctly states here, it is not available in .NET Core. Not all hope is lost for configuration-file based settings – dependency injection can be used to pass around the settings (see his post on the matter, or the documentation, for more information). Thus far, I’ve found nothing of this nature that prevented me from continuing with the project. The pieces seem to all be there, and may just be implemented in a different way.

From logging to dependency injection, unit testing to data access, and many things in-between, ASP.NET Core has proven to me that it is a stable, reliable option to make cross-platform APIs. If you have a project coming up that could use flexibility, extensibility and mobility, and/or you would like to work with some really interesting technology, I recommend this stack to you.

How To Perform A Natural Sort On A List Of Numbers

Hello everyone,

For those who have no idea what the title is about, the post will explain it in due time.

In my log parsing project that I’ve written about in previous posts, I’ve received new requirements to parse another type of log. This type of log has nearly no similarity to the other logs, so parsing this was a whole new ball game. For the sake of keeping this post focused, I’ll go into more details on the new stuff I added at a later date.

These new logs had messages which were associated with threads. These messages would show the initiation of an action, and would log all steps of that action until its success or failure, along with the times that these actions occurred. The new requirements stated that I must show the time the thread started, the amount of time the thread ran, the thread’s ID number and any error message in the case of a failure. I’d gathered this data, used DateTime to parse the times, and then used the Subtract method to find the difference between the first and last message of the thread. I then inserted this TimeSpan output into my custom class object as a string, not knowing the trouble I was stumbling into.

This list of times should be sorted by this difference in descending order, so I performed an OrderByDescending sort in LINQ. However, it sorted them in this fashion: 1, 10, 100, 2, 20, 200, 3, 30, 300, etc. This is because it’s being sorted in ASCII order (computer-friendly) instead of natural order (human-friendly). It would have sorted just fine if my number was stored in an int, but because it was in a string, it sorted it in this fashion. Considering I couldn’t change the type in the class without breaking other things, and using another class for this one scenario would be a bit overkill in my opinion, I searched for other options.

One option was padding, either with zeroes or with spaces. Although this wouldn’t look very pretty, it would solve the problem. This is because zero and a space are both valid ASCII, so they would be sorted in natural order, like so (if using spaces):
1
2
3
10
20
30
100
200
300

The TimeSpan output to a string already is padded, as it’s in a HH:MM:SS.SSS. So, if my time difference was 1 minute, 10 seconds, it would read 00:01:10.000. If I then have a difference of 1 minute, 9 seconds, it would read 00:01:09.000, and so it would be sorted below the first when in descending order. This is the way I did it, because I’m attempting to make a log summarizer. A user would need to read through this summary quickly, so having fields of equal length make reading it easy. Also, it doesn’t give the summary a ‘staircase’ look to it (like the example above).

Also, one could convert the string to an int. This would be a good solution, because LINQ’s OrderBy and OrderByDescending could be used to easily sort this in a natural way. However, TimeSpan or padding may work well as well. It’s a case of figuring out what’s best for your scenario.

…and that’s all I know at this point. Please feel free to give suggestions/comments.

Thanks for reading!

Learning New (And Secure) Tricks

Last time, I’d explained the start of my form, where I’m now adding items to a list and then adding those items to a checkboxlist. I also said in the last post that I wanted to give users the ability to delete items from the list in case any mistakes were made. This one actually wasn’t too hard to do, but it was difficult at first because I didn’t know the syntax to get it done.

On the event that the Remove button is clicked, I do a foreach loop through the checkboxlist. For each checkbox that’s selected, I remove the item from the list _items based on the checkbox item’s value. Note: when I first did this, I was trying to remove the items from the checkboxlist. That didn’t work, because every time the page reloads, all the items from _items repopulates the checkboxlist, so it just comes right back. It has to be deleted from the source for it to work.

void btn_remove_Click(object sender, EventArgs e)
        {
            ItemNumberRepository _myTempDatabase = new ItemNumberRepository();
            foreach (ListItem checkbox in UPCList.Items)
            {
                if (checkbox.Selected)
                {
                    _items.Remove(checkbox.Value);
                }
            }
            PopulateItemsList();
        }

At this point, I had the ability to add and delete. I’m done, right?… Wrong. Considering this information is pretty sensitive stuff, I wanted to be able to keep track of when items were added and by whom. Also, since two people were going to be keying this information in, I needed a centralized database for them both to add to. Thankfully, we had an instance of MS SQL that wasn’t being used heavily, so I started asking questions about how I can add my items to an SQL table. There’s some frameworks that help, but Matt Groves encouraged me to start humbly by using ADO.NET. That way I know exactly how it all works without being pampered by a framework.

I first started by getting a background of how and why ADO.NET was created. Wikipedia has a pretty good post about it, but I didn’t confirm the resources, so reader beware. I then took a look at the ADO.NET Overview on MSDN, which has many links to great resources that’ll teach about all you’d want to know about it. Also, a quick search through Pluralsight’s library can bring up many good examples and resources.

After wrapping my head around the fundamentals, I jumped in and started writing. I didn’t want to hit the database too much, so I decided to do a final submit that would send the entire list in one shot instead of sending each item individually. However, my boss wants me to have a backup in case the machine crashes in the middle of data entry, so I may go with adding individually if I can’t find a better solution. Enough about that though; on to the code! First, you need a connectionString that specifies what server and table to connect to. This can be put in the config of the project, but I’ve been lazy and just haven’t done it yet. Next, I do a for loop to run through all the items in the checkboxlist and run a command to add all the items into the table and add the account number that’s typed into the acctNum field on each field.

protected void final_submit_Click(object sender, EventArgs e)
        {
            string connectionString =
            "Data Source=server;Initial Catalog=table;"
            + "User Id=userid;"
            + "Password=password;";

            using (SqlConnection connection = new SqlConnection(connectionString))
            {
                for (int i = 0; i < UPCList.Items.Count; i++)
                {
                    string acctnum = AcctNum.Text;
                    string finalSubmit =
                        "INSERT INTO Boxes (BoxNumber)"
                        + "VALUES (@boxnumber)"
                        + "INSERT INTO DestructionOrder (AccountNumber)"
                        + "VALUES (@accountNumber)";

                    SqlCommand command = new SqlCommand(finalSubmit, connection);
                    command.Parameters.AddWithValue("@boxnumber", UPCList.Items[i].ToString());
                    command.Parameters.AddWithValue("@accountNumber", acctnum.ToString());
                    command.Connection.Open();
                    command.ExecuteNonQuery();
                    command.Connection.Close();
                }
            }
        }

The variables @boxnumber amd @accountNumber are parameters that are passed in instead of the live data from the textboxes. This will stop people from being able to inject SQL into my form and mess around with my tables. More info about this and many other security issues can be found at Keith Brown’s ASP.NET Security Pluralsight course.

The insert here is pretty simple: you specify which table (Boxes) and which column (BoxNumber) the data (@boxnumber) should go into (FYI: The pluses(+) are necessary if you decide to put your query on more than one line. They’re not necessary if you put your entire query on the same line). After that, you have to open your connection, execute the command and then close the connection. I would explain why closing the connection immediately is necessary in more detail, but I think Keith Brown does an amazing job at it, so just go watch that.

Well, that’s it for this week. I’m writing this to help people out where I’ve struggled in the past, so if you know anyone that’s new to ASP.NET, webforms, or ADO.NET, please share this with them…and once again, thanks for reading!