<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Seth A Burleson</title>
    <description>The latest articles on DEV Community by Seth A Burleson (@sbrevolution5).</description>
    <link>https://dev.to/sbrevolution5</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F608964%2Fd8532ab8-0762-44fd-9508-a38d09cbb78e.jpeg</url>
      <title>DEV Community: Seth A Burleson</title>
      <link>https://dev.to/sbrevolution5</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sbrevolution5"/>
    <language>en</language>
    <item>
      <title>Recipes, conversions, and fractions; or how I wrote part of my C# app.</title>
      <dc:creator>Seth A Burleson</dc:creator>
      <pubDate>Tue, 20 Jul 2021 18:47:44 +0000</pubDate>
      <link>https://dev.to/sbrevolution5/recipes-conversions-and-fractions-or-how-i-wrote-part-of-my-c-app-3pni</link>
      <guid>https://dev.to/sbrevolution5/recipes-conversions-and-fractions-or-how-i-wrote-part-of-my-c-app-3pni</guid>
      <description>&lt;h1&gt;
  
  
  Read this post on my blog!
&lt;/h1&gt;

&lt;p&gt;To read on my personal blog platform, &lt;a href="https://thecoderscodex.herokuapp.com/Posts/Details?slug=recipes-conversions-and-fractions-or-how-i-wrote-part-of-my-c-sharp-app"&gt;click here!&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Why is this post here?
&lt;/h1&gt;

&lt;p&gt;I wanted to journal about what I'd done to solve an annoying problem that I couldn't quite find a solution for online, partially to &lt;/p&gt;

&lt;h1&gt;
  
  
  App Premise
&lt;/h1&gt;

&lt;p&gt;The idea of the app is that a user can select recipes from a database, and plan to eat them later in the week.  The app can then provide a master shopping list that converts 2 lbs Chicken and 8oz chicken, into a consolidated "2 1/2 lbs chicken(40oz)" so that shopping is simpler.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Problem
&lt;/h1&gt;

&lt;p&gt;After setting up my database models (which I may post about at a later date) I realized that there was a major issue converting cooking measurements into code: fractions.  One half was easy to represent as a float or double, its a finite number.  The problem arose when we added in thirds (which you hopefully know, repeat infinitely).  I didn't want to add 3 recipies each calling for a third of a cup of sugar, and then have the list say "You need to buy .9999999..... cups of sugar." Rounding could be a solution, but it seemed like an awkward way of doing things.&lt;/p&gt;

&lt;h1&gt;
  
  
  The initial Idea
&lt;/h1&gt;

&lt;p&gt;What would be best is if there was a library to use to convert things to and from measurements.  This was what I first attempted, using &lt;a href="https://github.com/angularsen/UnitsNet"&gt;The UnitsNet library&lt;/a&gt;.  This library is excellent, and I recommend it to many people.  The issue I have with it, is that it was far more in depth than what I need it to do.  &lt;/p&gt;

&lt;p&gt;The other problem was saving its measurements in my database, it was becoming painful to implement, and I knew there needed to be a better avenue.&lt;/p&gt;

&lt;h1&gt;
  
  
  The solution
&lt;/h1&gt;

&lt;p&gt;After MUCH deliberation, I had a comment on a stackoverflow post suggest turning the measurements into an integer, which got me thinking.  I eventually settled on this idea, and while I came up with the volume solution first, the solution for weight measurement is much easier to explain.  &lt;/p&gt;

&lt;p&gt;When using meat, usually you're going to measure it in pounds or ounces, with the smallest unit generally being a half ounce.  So I'm translating 1 Oz to 2 "units", and a pound to 32 "units."  With a simple integer, it is possible to easily store it in the database, and also add different measurements together.  Once we decode the measurement "32", knowing it is measuring mass (which is done with a property on the ingredient object), we get one pound.  &lt;/p&gt;

&lt;p&gt;I've done a similar thing with volume, where the base "unit" is 1/24th of a teaspoon.  therefore a teaspoon is 24 units, a tablespoon is 72 units, a cup is a lot more (24*3*2*8) units.  &lt;/p&gt;

&lt;p&gt;You can look at the methods in &lt;a href="https://github.com/sbrevolution5/MasterMeal/blob/master/MasterMeal/Services/MeasurementService.cs"&gt;the service on my GitHub&lt;/a&gt; which as of today (7/20/21) is mostly complete, but still has some issues that I've got to figure out. &lt;/p&gt;

&lt;h1&gt;
  
  
  The remaining issues.
&lt;/h1&gt;

&lt;p&gt;Right now, the "units" are converted to the largest possible measure.  This seems like a fine solution, until you call for "1/4 Tablespoon" (18 units) and you get back "3/4 Teaspoons".  This isn't wrong, in fact its the exact correct measurement, but when baking/cooking its more practical to have it in a smaller unit.  Another similar case is "2 Teaspoons" (48 units), which can turn into "2/3 Tablespoons" (also 48 units).  It isn't wrong, but it isn't the best response.  &lt;/p&gt;

&lt;p&gt;I'm considering fixing this a couple ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Allow the user to specify the kind of measurement that should be used.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is rather unfeasible, because if there are two recipes by different users, and one measures milk in a tablespoon, but the other measures it in a cup, the program has to decide what takes precedence.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hard code certain measurements&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'm considering hard coding 1/4 tbsp, 1 tsp, 1/2 tbsp, 2tsp, 3/4 tbsp, and 1 tbsp.  This would ensure I always get the right kind of measurements.  My concern is that it could be confusing to the user if they initially put in 3/4 Teaspoon, but it shows up as 1/4 tablespoon.  They could figure out that its equivalent with some math, but it could be a confusing occurance to a first time user.  &lt;/p&gt;

&lt;p&gt;Any suggestions on which implementation should be used?&lt;br&gt;&lt;br&gt;
Has anyone else solved this problem a different way?  &lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>TransFORMing your Forms</title>
      <dc:creator>Seth A Burleson</dc:creator>
      <pubDate>Mon, 21 Jun 2021 15:18:09 +0000</pubDate>
      <link>https://dev.to/sbrevolution5/transforming-your-forms-53nb</link>
      <guid>https://dev.to/sbrevolution5/transforming-your-forms-53nb</guid>
      <description>&lt;p&gt;&lt;a href="https://thecoderscodex.herokuapp.com/Posts/Details?slug=transforming-your-forms"&gt;Read it on my blog!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On my new Bugtracker project (Try it out &lt;a href="https://jamesonbugtracker.herokuapp.com"&gt;here!&lt;/a&gt;) I was putting together a button that the user can use to change the state of the project, but I needed this button, and other page elements, to change based on that state.  &lt;/p&gt;

&lt;p&gt;The big frustration was that when I clicked the button, it was refreshing the page, meaning if a user had a new ticket, finished development and testing, they had reloaded the page a few times without seriously changing the data.  I wanted to change the data without refreshing the page, which was where I learned about AJAX, and my life changed completely....&lt;/p&gt;

&lt;p&gt;A few things to realize before we start, I'm using the &lt;a href="https://adminlte.io/"&gt;AdminLTE template&lt;/a&gt; for most of my formatting on this project.  The project is written on the C# stack, but it will work fine for other tech such as Node, flask, or any framework that uses MVC.  Most of what we're discussing here is frontend.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Keeping it fresh, without refresh
&lt;/h1&gt;

&lt;p&gt;Before I implemented ajax, I had a controller action which updated the status when the form (which only contains a button and hidden input) submitted, it then returned the new Ticket Details page.  At first, I used this action with ajax to perform the same action without refreshing.&lt;br&gt;&lt;br&gt;
First, lets look at my form, which submits to the MVC action, "/Tickets/UpdateStatus":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form asp-action="UpdateStatus" id="toTesting" class="updateStatus"&amp;gt;

                    &amp;lt;input hidden name="ticketId" value="@Model.Id" /&amp;gt;
                    &amp;lt;input hidden name="statusName" class="statusName" value="Testing" /&amp;gt;
                    &amp;lt;button class="updateBtn btn btn-block btn-warning" type="submit"&amp;gt;Update to Testing&amp;lt;/button&amp;gt;
                &amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the basic code used for the ajax request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$(".updateStatus").on("submit", function (e) {

    //SETUP
    var dataString = $(this).serialize();
    var newStatus = $(this).children(".statusName")[0].value
   //AJAX Function
    $.ajax({
        type: "POST",
        url: "/Tickets/UpdateStatus",
        data: dataString,
//Result Area
        success: function (result) {
            toastr.success(`Ticket Status was updated`)
        },
        error: function (result) {
            toastr.danger("Something went wrong, status wasn't updated")

    });
//While We wait
    e.preventDefault();
    toastr.info('Updating Ticket Status. Please Wait')
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pay attention to the comments I left, I'll be referring to them as we enhance the call to interact with our page.  &lt;/p&gt;

&lt;p&gt;First off, I strongly recommend using toastr for easy toasts, The three lines you see (plus a script import tag) are all I had to write for a simple toasting service that showed the user temporary alerts.&lt;/p&gt;

&lt;p&gt;You'll notice that this function seems a bit out of order, Lets walk through it real quick.  At the top, we get any of the elements with the updateStatus class, and tell them to perform this function on submit.  For the moment, Lets skip over the block beginning with &lt;code&gt;$.ajax(&lt;/code&gt; and look at the "while we wait" section.  This is what happens on the page when our request is made, but before a response comes back from the server.  The important thing is &lt;code&gt;e.preventDefault();&lt;/code&gt; which stops the form from being submitted as normal, which would refresh the page.  Then we use Toastr to tell the user to hold on a moment.  &lt;/p&gt;

&lt;p&gt;When the result comes back from our ajax call, if its successful, we show the user a success toast, if there was an error, we inform them.  &lt;/p&gt;

&lt;p&gt;We now have a button that updates our ticket to testing, and it works, but we can make it work better and look better as well.&lt;/p&gt;

&lt;h1&gt;
  
  
  One at a time please
&lt;/h1&gt;

&lt;p&gt;Some users (I've certainly been guilty) are impatient, and will click the button over and over if they don't think its working, despite what your please wait message says.  Why not prevent that by disabling the button while the request is processed?  &lt;/p&gt;

&lt;p&gt;My button has the class &lt;code&gt;updateBtn&lt;/code&gt; so jQuery can find it.  In the setup part of the function, lets add &lt;code&gt;$(".updateBtn").attr("disabled", true)&lt;/code&gt; so that the button will be disabled after the form is submitted.  Once we get a success or error, we want to re-enable that button, so in both properties, I'm adding the following line to our function: &lt;code&gt;$(".updateBtn").attr("disabled", false)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now your form can't be submitted again until one request has either succeeded or returned an error, despite users who have an itchy trigger finger.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Changing the button
&lt;/h1&gt;

&lt;p&gt;I'm going to come clean here, there is more than one button on this page, but theres no need to see them all at once.&lt;br&gt;&lt;br&gt;
The four buttons that are on my page are&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form asp-action="UpdateStatus" id="toTesting" class="updateStatus"&amp;gt;

                    &amp;lt;input hidden name="ticketId" value="@Model.Id" /&amp;gt;
                    &amp;lt;input hidden name="statusName" class="statusName" value="Testing" /&amp;gt;
                    &amp;lt;button class="updateBtn btn btn-block btn-warning" type="submit"&amp;gt;Update to Testing&amp;lt;/button&amp;gt;
                &amp;lt;/form&amp;gt;

                &amp;lt;form asp-action="UpdateStatus" id="returnTesting" class="updateStatus"&amp;gt;

                    &amp;lt;input hidden name="ticketId" value="@Model.Id" /&amp;gt;
                    &amp;lt;input hidden name="statusName" class="statusName" value="Development" /&amp;gt;
                    &amp;lt;button class="updateBtn btn btn-block btn-danger" type="submit"&amp;gt;Testing Failed: Return to Development&amp;lt;/button&amp;gt;
                &amp;lt;/form&amp;gt;
                &amp;lt;form asp-action="UpdateStatus" id="closeTicket" class="updateStatus"&amp;gt;

                    &amp;lt;input hidden name="ticketId" value="@Model.Id" /&amp;gt;
                    &amp;lt;input hidden name="statusName" class="statusName" value="Resolved" /&amp;gt;
                    &amp;lt;button class="updateBtn btn btn-block btn-success mt-2" type="submit"&amp;gt;Close Ticket&amp;lt;/button&amp;gt;
                &amp;lt;/form&amp;gt;
                &amp;lt;form asp-action="UpdateStatus" id="reopenTicket" class="updateStatus"&amp;gt;


                    &amp;lt;input hidden name="ticketId" value="@Model.Id" /&amp;gt;
                    &amp;lt;input hidden name="statusName" class="statusName" value="Development" /&amp;gt;
                    &amp;lt;button class="updateBtn btn btn-block btn-success" type="submit"&amp;gt;Reopen Ticket to Development status&amp;lt;/button&amp;gt;
                &amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But we only need to see some of these at a time.  &lt;/p&gt;

&lt;p&gt;I wrote a small js function to handle this using Jquery's fadeIn and fadeOut methods (originally I used .show and .hide, but this produced a strange transition where things grew from the top left corner.)  You just pass in the new status name and the time in ms for the fade to happen. &lt;/p&gt;

&lt;p&gt;(ticketstatus is defined with my C# model: &lt;code&gt;var ticketStatus = "@Model.TicketStatus.Name"&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var toTesting = $("#toTesting")
var returnTesting = $("#returnTesting")
var closeTicket = $("#closeTicket")
var reopenTicket = $("#reopenTicket")
function statusButtons(status, num) {
    if (status == "Development") {
        toTesting.fadeIn(num)
        returnTesting.fadeOut(num)
        reopenTicket.fadeOut(num)
        closeTicket.fadeOut(num)
    }
    else if (status == "Testing") {
        toTesting.fadeOut(num)
        returnTesting.fadeIn(num)
        reopenTicket.fadeOut(num)
        closeTicket.fadeIn(num)
    }
    else if (status == "Resolved") {
        toTesting.fadeOut(num)
        returnTesting.fadeOut(num)
        reopenTicket.fadeIn(num)
        closeTicket.fadeOut(num)
    }
    else{
        toTesting.fadeOut(num)
        returnTesting.fadeOut(num)
        reopenTicket.fadeOut(num)
        closeTicket.fadeOut(num)
    }
}
statusButtons(ticketStatus,0)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I use Ids to reference each button, and then based on the status, we fade certain ones in or out.&lt;br&gt;&lt;br&gt;
We then call this right after definition, with a fade time of 0, to ensure that only the correct buttons are shown.  &lt;/p&gt;

&lt;p&gt;I then call this function when the successful result happens.  If there was an error, we never changed our data, so theres no need to call the function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;success: function (result) {
            toastr.success(`Ticket Status was updated`)
            ticketStatus = newStatus
            $("#ticketStatusText").text(ticketStatus)
            statusButtons(ticketStatus, 600)
            $(".updateBtn").attr("disabled", false)

        },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;newStatus comes from the hidden input within the form.  &lt;/p&gt;

&lt;p&gt;That should get you started making ajax calls without reloading the page, and give you the oppourtunity to expand.  Take a look at the finished result on a ticket details page at the &lt;a href="https://jamesonbugtracker.herokuapp.com"&gt;Jameson Bug Tracker&lt;/a&gt; (Log in as a demo project manager and then click on any ticket's details)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kSuw-wc5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rd7ba2gi484m2p1hmtnp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kSuw-wc5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rd7ba2gi484m2p1hmtnp.gif" alt="See it in action"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me know what you think in the comments!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>css</category>
      <category>html</category>
    </item>
    <item>
      <title>Creating a toggleable dark mode theme</title>
      <dc:creator>Seth A Burleson</dc:creator>
      <pubDate>Thu, 03 Jun 2021 20:47:37 +0000</pubDate>
      <link>https://dev.to/sbrevolution5/creating-a-toggleable-dark-mode-theme-ned</link>
      <guid>https://dev.to/sbrevolution5/creating-a-toggleable-dark-mode-theme-ned</guid>
      <description>&lt;p&gt;Read it on &lt;a href="http://thecoderscodex.herokuapp.com/Posts/ViewPost/creating-a-toggleable-dark-mode-theme"&gt;My Blog, The Coder's Codex&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It can be surprisingly simple to add a dark mode toggle to your site, but the challenging part can be making that choice persist for the user throughout your app.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Allowing the toggle
&lt;/h1&gt;

&lt;p&gt;I'm using AdminLTE as a template(its free to download and its great), which luckily has a wonderful little class ("dark-mode") that can be applied to the body to quickly apply a dark theme to the whole site.  Adding a button with the onclick function "toggleDark()" allowed me to access the function I wrote in my site.js file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function toggleDark() {
    var element = document.getElementById("layoutBody")
    element.classList.toggle("dark-mode")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That was really all it took to be able to toggle, once I added the #layoutBody Id to my body element.  Then came the tougher part, making that persist across multiple pages&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Saving user preference to Localstorage
&lt;/h1&gt;

&lt;p&gt;Using localstorage, we can save the user's preference to the browser.  &lt;/p&gt;

&lt;p&gt;I wrote a function called loadDark() that takes care of this, and called it using jquery.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function loadDark() {
    //default is light mode
    console.log("dark mode is ", JSON.parse(localStorage.getItem("jamesonDarkMode")))
    let dark = JSON.parse(localStorage.getItem("jamesonDarkMode"))
    if (dark === null) {
        localStorage.setItem("jamesonDarkMode", JSON.stringify(false))
    }
    else if (dark === true) {
        document.getElementById("layoutBody").classList.add("dark-mode")
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the Jquery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;script&amp;gt;
        $(window).on("load",loadDark());
    &amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a default user preference, but theres no way to change it yet.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Changing the user preference
&lt;/h1&gt;

&lt;p&gt;Now back in our other function, we need to add some stuff to our toggleDark functionchange that localStorage variable.  Otherwise we will only ever have the default setting of false.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function toggleDark() {
    var element = document.getElementById("layoutBody")
    element.classList.toggle("dark-mode")
    let dark = JSON.parse(localStorage.getItem("jamesonDarkMode")) 
    if (dark) {
        localStorage.setItem("jamesonDarkMode", JSON.stringify(false))
        console.log("Dark mode off")
    }
    else {
        localStorage.setItem("jamesonDarkMode", JSON.stringify(true))
        console.log("Dark mode on")
    }
    //optional to change fontawesome icon on button
    var buttonElement = document.getElementById("darkIcon")
    buttonElement.classList.toggle("fa-moon")
    buttonElement.classList.toggle("fas")
    buttonElement.classList.toggle("far")
    buttonElement.classList.toggle("fa-sun")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now whenever the user clicks the button the localstorage variable will be updated, and saved across your site.  &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>css</category>
      <category>design</category>
    </item>
    <item>
      <title>Writing my first C# MVC Unit Test</title>
      <dc:creator>Seth A Burleson</dc:creator>
      <pubDate>Tue, 18 May 2021 14:29:12 +0000</pubDate>
      <link>https://dev.to/sbrevolution5/writing-my-first-c-mvc-unit-test-13ah</link>
      <guid>https://dev.to/sbrevolution5/writing-my-first-c-mvc-unit-test-13ah</guid>
      <description>&lt;p&gt;After much research and thought, I'm diving in today with a very basic C# unit test, just to get my feet wet with Test Driven Development.  The purpose of this test, is to see if the home index will return 2 blogs.  It should be very simple, and I honestly rarely expect this test to break, but you've got to start somewhere!&lt;/p&gt;

&lt;h1&gt;
  
  
  The setup.
&lt;/h1&gt;

&lt;p&gt;I've Installed the xUnit extension into VS2019, and I'm adding a new xUnit Test Project to my solution.  Since this is for my blog project, I'll name it BlogTests, and put it in my project folder.  This creates a sample test with nothing in it at the moment, but we will fix that shortly.   &lt;/p&gt;

&lt;h1&gt;
  
  
  Auto-generated "Tests"
&lt;/h1&gt;

&lt;p&gt;One of the great things about VS2019 is that it can generate a "test" for you.  This test doesn't do anything, but it gives us a starting point.  Over in the main project's home controller, if we right click inside the index action (you can right click inside the overall class to make more than one test at once if needed) and go to "Create Unit tests" we get a lovely pop-up that gives us some options.  If its not already selected, make sure the Test Framework is xUnit.net 2.0, then select your test project, and &lt;code&gt;&amp;lt;New Test File&amp;gt;&lt;/code&gt; before you hit OK.  I'm having it assert failure for all tests right now, since there isn't anything going on just yet.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Mocking the database
&lt;/h1&gt;

&lt;p&gt;With EFCore, we actually don't have to make a Mock database, we will instead use the local database for testing.   It was rather difficult to get the Mock database working with EFCore, and in my research it turned out to be unnecessary.&lt;/p&gt;

&lt;h1&gt;
  
  
  Writing the test itself
&lt;/h1&gt;

&lt;p&gt;Once we have our Mock Database, we are ready to write the test.  Lets use a more descriptive name than "Index Test".  There are 3 parts considered standard to a test name:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The behavior being tested&lt;/li&gt;
&lt;li&gt;The constraints&lt;/li&gt;
&lt;li&gt;The expected behavior&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'm going to use "Index_ReturnsAViewResult_WithAPagedListOfFiveBlogs" as the name.  Its a mouthful, but if my test fails I will immediately know what failed.&lt;/p&gt;

&lt;p&gt;There are now 3 parts to our test: Arrange, Act, and Assert.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arrange
&lt;/h2&gt;

&lt;p&gt;This step involves putting the data in the correct spot, and performing any setup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var optionsBuilder = new DbContextOptionsBuilder&amp;lt;ApplicationDbContext&amp;gt;();
            optionsBuilder.UseNpgsql(Connection.GetConnectionString(_configuration));
            var _dbContext = new ApplicationDbContext(optionsBuilder.Options);

            var controller = new HomeController(null,_dbContext);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The optionsBuilder is used to configure options for the ApplicationDbContext, which then is passed to the controller.  I did not pass the controller a logger at this point, since I am not using the logger to test.  Your options builder should take the same arguments that are used in startup.cs to set up your database.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Act.
&lt;/h2&gt;

&lt;p&gt;This part is very simple, just get a result from the controller&lt;br&gt;
&lt;code&gt;var result = await controller.Index(1); //passing page 1&lt;/code&gt;&lt;br&gt;
I'm passing a variable because my site is using X.PagedList to paginate (see &lt;a href="https://dev.to/sbrevolution5/3-steps-to-paging-in-asp-net-blog-part-3-371m"&gt;this post&lt;/a&gt;)&lt;/p&gt;
&lt;h2&gt;
  
  
  Assert
&lt;/h2&gt;

&lt;p&gt;And here's the meat and potatoes, We're going to check that the type is ViewResult, and the model is based on an IPagedList.  Then finally, we ensure that the model only includes 5 items for this page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var viewResult = Assert.IsType&amp;lt;ViewResult&amp;gt;(result);
            var model = Assert.IsAssignableFrom&amp;lt;IPagedList&amp;lt;Blog&amp;gt;&amp;gt;(viewResult.Model);
            Assert.Equal(5, actual: model.Count());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run a test, we use a series of "assert" statements.  If any of these fail, we will recieve a failure on a test.  This is where we're going to stop for now, but as a first experiment in testing, I'd call this a success.  &lt;/p&gt;

&lt;p&gt;My main struggle at the moment is coming up with the right kind of tests.  Unlike working with a very math based console app, I don't feel like I have much to test within the controllers.  &lt;/p&gt;

&lt;p&gt;What kinds of tests do you do with MVC apps? &lt;/p&gt;

</description>
      <category>testing</category>
      <category>csharp</category>
      <category>dotnet</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Whats an Interface?</title>
      <dc:creator>Seth A Burleson</dc:creator>
      <pubDate>Fri, 14 May 2021 21:59:43 +0000</pubDate>
      <link>https://dev.to/sbrevolution5/whats-an-interface-5dgf</link>
      <guid>https://dev.to/sbrevolution5/whats-an-interface-5dgf</guid>
      <description>&lt;p&gt;Interfaces can be confusing for beginner programmers, but I think I have the right analogy to explain them in simple terms.&lt;/p&gt;

&lt;p&gt;Imagine with me for a moment, that you were born into a wealthy family, so wealthy that you need not do very much for yourself, and especially not be bothered with transportation.  You even hired the best chauffeur that can handle any vehicle.&lt;/p&gt;

&lt;p&gt;The only thing required of you is selecting a vehicle, everything else will be taken care of.  If you're to be transported somewhere, you'll need that vehicle to have at least 3 functionalities:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A place for the driver or operator.&lt;/li&gt;
&lt;li&gt;A place for you to sit.&lt;/li&gt;
&lt;li&gt;some way to move.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There are obviously other things, but they don't concern you.  You just need the basics.  Does a car fit this description?  Yes of course, you have both seats, and it can travel along a road or path.  Does a commercial airplane fit the description?  Yes again, even though there might be extra seats, it can take you somewhere. even though it does it differently than a car would. A bench would not satisfy the requirements, even though it has 2 seats, it goes nowhere.  &lt;/p&gt;

&lt;p&gt;This is what an interface calls for, an object that can do certain things.  It doesn't care how they get done, as long as the user (or the controller in an MVC app) says "GO" it knows it can go.  &lt;/p&gt;

&lt;p&gt;Just a quick analogy today.  Have a great weekend everybody!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>webdev</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>3 steps to Paging in ASP .NET | Blog part 3</title>
      <dc:creator>Seth A Burleson</dc:creator>
      <pubDate>Wed, 12 May 2021 17:14:41 +0000</pubDate>
      <link>https://dev.to/sbrevolution5/3-steps-to-paging-in-asp-net-blog-part-3-371m</link>
      <guid>https://dev.to/sbrevolution5/3-steps-to-paging-in-asp-net-blog-part-3-371m</guid>
      <description>&lt;p&gt;Adding paging to your asp .NET site can be simple.  All we need to do is add a few simple nuget packages, and edit the controller and View.  Lets get started!&lt;/p&gt;

&lt;h1&gt;
  
  
  The Nuget packages
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/asI6WBJXOn30I/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/asI6WBJXOn30I/giphy.gif" alt="Package"&gt;&lt;/a&gt;&lt;br&gt;
We're going to need a few packages to implement paging easily.  The easy one is X.PagedList (find it &lt;a href="https://www.nuget.org/packages/X.PagedList" rel="noopener noreferrer"&gt;here&lt;/a&gt;) but you'll also need &lt;a href="https://www.nuget.org/packages/X.PagedList.Mvc.Core/" rel="noopener noreferrer"&gt;X.PagedList.Mvc.Core&lt;/a&gt; for the MVC functionality, and &lt;a href="https://www.nuget.org/packages/X.PagedList.Web.Common/" rel="noopener noreferrer"&gt;X.PagedList.Web.Common&lt;/a&gt; for styling.  &lt;/p&gt;
&lt;h1&gt;
  
  
  Adding logic to our controller.
&lt;/h1&gt;

&lt;p&gt;In the controller for the view that requires paging (mine is my home index, but it could be elsewhere depending on the project) we need some variables to determine pages.  First off, lets add a nullable int to the parameters called page.  To handle the case where it is null, we use the null coalescing operator to default to page 1.  Our page size will determine how many elements (in my case: blogs) go on each page, 5 is probably a good number for me, but choose what fits your site the best.  &lt;/p&gt;

&lt;p&gt;Once we retrieve posts from the database, we'll order the posts by when they were created (you can take this part of Linq out if it doesn't make sense for your project) and then make a paged list using our new function.  I'm then passing the blogs into my view.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task&amp;lt;IActionResult&amp;gt; Index(int? page)
        {
            //handles case of no page given, in that case give it the first page.
            var pageNumber = page ?? 1;
            var pageSize = 5;

            var pagedBlogs= await _context.Blog.OrderByDescending(b=&amp;gt;b.Created).ToPagedListAsync(pageNumber,pageSize);
            return View(pagedBlogs);
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you add any missing directives, that takes care of the controller.&lt;/p&gt;

&lt;h1&gt;
  
  
  Handling our view
&lt;/h1&gt;

&lt;p&gt;Over in the view (mine is index) at the bottom of your page, lets add a line that shows the user which page they are on, and how many total pages there are.  &lt;code&gt;Page @(Model.PageCount &amp;lt; Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount&lt;/code&gt; will work, assuming you followed the same naming conventions.  Feel free to customize the Text to match the nature of your project, but leave the Model attributes the same.&lt;/p&gt;

&lt;p&gt;After that, we'd like have a navigation element that lets users go to the previous or next page.  You'll need the directive &lt;code&gt;@using X.PagedList.Mvc.Core&lt;/code&gt; as well as the related nuget package (which you should have installed in part 1).  The line to do this is &lt;code&gt;@Html.PagedListPager(Model, page =&amp;gt; Url.Action("Index", new { page = page }))&lt;/code&gt; and you're done!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw81kokrld2og1h35wdft.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw81kokrld2og1h35wdft.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Its functional, but it looks hideous.  This is why we need the X.PagedList.Web.Common, Adding a parameter to our @Html element allows us to change a few options and make it pretty with some bootstrap classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Html.PagedListPager(Model, page =&amp;gt; Url.Action("Index", new { page = page }),
                    new PagedListRenderOptions
                    {
                        LiElementClasses = new string[] { "page-item"},
                        PageClasses = new string[] {"page-link"}
                    } 
               )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mine ended up looking like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9sppwe452j5zb3e4vue4.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9sppwe452j5zb3e4vue4.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you have a beautiful paged layout.  Comment below with your ideas for styling the Elements and page classes.  I'm using some of the most basic bootstrap elements.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks for reading
&lt;/h2&gt;

&lt;p&gt;With your new paged layout, users don't have to load all of your content at once, and can navigate back and forth.  My next step is to add this kind of functionality to my posts for each blog.  What kind of project are you using this on?  &lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Simple MVC Security in ASP.NET | Blog Security pt. 2: Permission and Display</title>
      <dc:creator>Seth A Burleson</dc:creator>
      <pubDate>Fri, 07 May 2021 16:51:04 +0000</pubDate>
      <link>https://dev.to/sbrevolution5/simple-mvc-security-in-asp-net-blog-security-pt-2-permission-and-display-pmh</link>
      <guid>https://dev.to/sbrevolution5/simple-mvc-security-in-asp-net-blog-security-pt-2-permission-and-display-pmh</guid>
      <description>&lt;p&gt;Part 2 in a series on security for an MVC blog site. &lt;a href="https://dev.to/sbrevolution5/simple-mvc-security-in-asp-net-blog-pt-1-313f"&gt;See Part 1 here&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: Let yourself back in.
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/yx400dIdkwWdsCgWYp/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/yx400dIdkwWdsCgWYp/giphy.gif" alt="let me in"&gt;&lt;/a&gt;&lt;br&gt;
So your application is now so secure that even you can't get in. &lt;br&gt;
Lets make a dataservice with a method that will call 2 other functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class DataService
    {
        /* Any injected services go here!!
           Don't forget the constructor!! */

        public async Task ManageDataAsync()
        {
            //Task 1: Seed roles (create and enter into Authorization system
            await SeedRolesAsync();
            // Task 2 seed a few users into AspNetUsers
            await SeedUsersAsync();
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used a dataservice to seed roles when there are none.  (this is the first method in that service)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public async Task SeedRolesAsync()
        {
            //Are there roles in the system? 
            if (_context.Roles.Any())
            {
                return;
            }
            //Spin through enum and do stuff
            foreach (var role in Enum.GetNames(typeof(BlogRole)))
            {
                //create Role in system for each role
                await _roleManager.CreateAsync(new IdentityRole(role));
            }
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;BlogRole is an enum with Administrator and Moderator are the options, so now we have 2 roles that exist in our database.&lt;/p&gt;

&lt;p&gt;Lets then seed an adminUser&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private async Task SeedUsersAsync()
        {
            if (_context.Users.Any())
            {
                return;
            }
            var adminUser = new BlogUser()
            {
                Email = "AdminEmail@AdminMailAddress.com",
                UserName = "AdminEmail@AdminMailAddress.com",
                FirstName = "Admin",
                LastName = "Istrator"
                //OTHER DATA FOR USER CLASS
            };
            await _userManager.CreateAsync(adminUser, _configuration["AdminPassword"]);
            await _userManager.AddToRoleAsync(adminUser, BlogRole.Administrator.ToString());


        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where my Admin Password is in my appSettings.json, to keep it private from github.  You may also use IdentityUser where I used BlogUser to initialize a user.&lt;/p&gt;

&lt;p&gt;The ManageDataAsync is called in your program.cs file&lt;br&gt;
Where the contents of main look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        public static async Task Main(string[] args)
        {
            //CreateHostBuilder(args).Build().Run();
            var host = CreateHostBuilder(args).Build();
            var dataService = host.Services.CreateScope().ServiceProvider.GetRequiredService&amp;lt;DataService&amp;gt;();
            await dataService.ManageDataAsync();

            host.Run();
        }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 4: Hiding things from the unregistered masses
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3Mjz7yKMBfScfNVBRg/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3Mjz7yKMBfScfNVBRg/giphy.gif" alt="invisible"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If a new unregistered user comes to my site, I don't want them to click on something that takes them to a page where access is denied.  In my view, I'll add a simple if statement&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@if (User.IsInRole("Administrator"))
                    {

                        &amp;lt;li class="nav-item"&amp;gt;
                            &amp;lt;a class="nav-link" asp-area="" asp-controller="Blogs" asp-action="Index"&amp;gt;Blogs&amp;lt;/a&amp;gt;
                        &amp;lt;/li&amp;gt;
                        &amp;lt;li class="nav-item"&amp;gt;
                            &amp;lt;a class="nav-link" asp-area="" asp-controller="Posts" asp-action="Index"&amp;gt;Posts&amp;lt;/a&amp;gt;
                        &amp;lt;/li&amp;gt;
                    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The inner content will be whatever you want to display to users in the administrator role.  Adding an &lt;code&gt;||&lt;/code&gt; to your if can allow for multiple roles, and else statements can be used to display different data for different roles.  &lt;/p&gt;

&lt;p&gt;An interesting idea is to give the user a gray button that redirects to a purchase page if they aren't a premium user, showing them what they're missing and giving them an option to upgrade.  &lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Simple MVC Security in ASP.NET | Blog Security pt. 1: Locking it down</title>
      <dc:creator>Seth A Burleson</dc:creator>
      <pubDate>Fri, 07 May 2021 16:40:36 +0000</pubDate>
      <link>https://dev.to/sbrevolution5/simple-mvc-security-in-asp-net-blog-pt-1-313f</link>
      <guid>https://dev.to/sbrevolution5/simple-mvc-security-in-asp-net-blog-pt-1-313f</guid>
      <description>&lt;p&gt;I'm working on a full fledged blog site ( I currently plan to post on dev.to as well, but its a project to show potential employers) and I've just learned how simple it is to implement security.  Its almost completely built in to the template, I'll show you how to leverage it to make your site more professional and secure. &lt;/p&gt;

&lt;h1&gt;
  
  
  What you need to get started
&lt;/h1&gt;

&lt;p&gt;I'm using my Blog project I've spent about a week on, but you don't need anything in depth to try this out.  What I'd recommend is a simple scaffolded MVC with ASP.NET Core, Setup your database however you like so it handles user accounts, and we can get started.&lt;/p&gt;

&lt;p&gt;As a quick overview, I have a few models, the ones we'll be working with are blogs (collections of posts) and posts.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Step 1: Denying access
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/8abAbOrQ9rvLG/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/8abAbOrQ9rvLG/giphy.gif" alt="You shall not pass"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my blog application currently anyone can edit the database, which is bad.  I don't want Anyone who stumbles on the site to be able to create a blog without registering and having permission from myself, and I definitely don't want them deleting my hard work.  So lets lock it down!&lt;/p&gt;

&lt;p&gt;In the controller for my blogs, right in front of my create get action, I'm going to add one simple line of code &lt;code&gt;[Authorize]&lt;/code&gt; and then ensure that the &lt;code&gt;using Microsoft.AspNetCore.Authorization;&lt;/code&gt; directive is at the top of my controller.  (use ctrl+. to fix this error when the red error ramen comes up).&lt;/p&gt;

&lt;p&gt;This Locks out any unregistered user from the page, and redirects them to the login page to put them on track.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Allowing a little access
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o6Mb2WBUzb7PGcgj6/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o6Mb2WBUzb7PGcgj6/giphy.gif" alt="unlocked"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since anyone can register, this is a bit like closing the door but leaving it completely unlocked.  If the user is smart enough to register (Most are) they're going to get through the rigorous security.  If we beef things up a little we can only allow administrators into the create blog posts.  &lt;code&gt;[Authorize(Role = "Administrator")]&lt;/code&gt; solves the problem.  They will be asked to log in, and then met with an access denied message instead of the ability to create a blog.  &lt;/p&gt;

&lt;p&gt;I'd rather them not access most of the blog controller, just the index of blogs.  Taking a more drastic measure is to instead add &lt;code&gt;[Authorize(Role = "Administrator)]&lt;/code&gt; to the entire class.  Now access denied will show up for all actions within the Blog controller.  On the Index and details actions, we can add &lt;code&gt;[AllowAnonymous]&lt;/code&gt; to ensure.  This will let Anonymous users back in, so they can browse the blogs and see their details. &lt;/p&gt;

&lt;p&gt;This works, but there is a pretty big oversight.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/xUySTL60dNkQJJGmnS/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/xUySTL60dNkQJJGmnS/giphy.gif" alt="Locked out "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The temporary fix is to remove the security so you can work on it.&lt;br&gt;&lt;br&gt;
We'll fix that in my next blog, which will cover Assigning roles and changing whats displayed to the user.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Customizing .NET's MVC template Part 2- Cards, Images, and transitions</title>
      <dc:creator>Seth A Burleson</dc:creator>
      <pubDate>Fri, 30 Apr 2021 19:51:09 +0000</pubDate>
      <link>https://dev.to/sbrevolution5/customizing-net-s-mvc-template-part-2-cards-images-and-transitions-4clo</link>
      <guid>https://dev.to/sbrevolution5/customizing-net-s-mvc-template-part-2-cards-images-and-transitions-4clo</guid>
      <description>&lt;p&gt;This is part two in a series on improving the MVC template, see &lt;a href="https://dev.to/sbrevolution5/customizing-net-s-mvc-template-part-1-the-dark-side-5doa"&gt;part 1 here.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's our starting point:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnooazxddg72ob0ozs1m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnooazxddg72ob0ozs1m.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Cards
&lt;/h1&gt;

&lt;p&gt;So I know we just got done making that table look nice, but we can do much better by switching it to display cards.  On the index page, let's use the foreach loop to show cards instead of rows on our table.  In my opinion, this makes the movies in the database look more appealing than just lines of data, and therefore improves user experience. To get the look right, make sure each card renders with a &lt;code&gt;bg-dark&lt;/code&gt; class. &lt;/p&gt;

&lt;p&gt;Wrapping these in a div with class &lt;code&gt;card-deck&lt;/code&gt; will make your card the same height, and allow footers to be aligned across multiple cards.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wudsfuzk0rilkajz39q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wudsfuzk0rilkajz39q.png" alt="Card take 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The thing I don't really care for is the way the cards blend into the background too easily.&lt;/p&gt;

&lt;p&gt;To fix this issue, lets add shadow to the cards with class &lt;code&gt;shadow-lg&lt;/code&gt;, and alter the background class to &lt;code&gt;bg-secondary&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;This will make the site look a lot better!&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsaxsqrfdxw5jjgbcal7i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsaxsqrfdxw5jjgbcal7i.png" alt="Cardv2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code for this looks like: &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdm0d3ae3zpat25snv2ut.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdm0d3ae3zpat25snv2ut.png" alt="Card Code"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Thumbnails
&lt;/h1&gt;

&lt;p&gt;I've built a custom image service to access images in my database, but if you have images stored with your model, an easy thing you can do is to add them to the top of the card.  &lt;/p&gt;

&lt;p&gt;The problem arrives when you add large images,  since the cards take the width of the container.  The simplest way to fix this is to use the bootstrap grid.  Wrapping each card in a div with a col size class (I personally used &lt;code&gt;col-sm-4&lt;/code&gt; to get 3 per row.) and also adding in a little margin to that column with &lt;code&gt;mb-3&lt;/code&gt;. Using &lt;code&gt;h-100&lt;/code&gt; in the card itself will scale the cards, and therefore the images, down to fit your specifications.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftodx70quua7o4sanhy9w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftodx70quua7o4sanhy9w.png" alt="Card Columns"&gt;&lt;/a&gt;&lt;br&gt;
This made it look like a &lt;code&gt;card-deck&lt;/code&gt; div without actually using the card-deck class.  I tried that out but it was putting all my cards on one row unless I was on a small screen. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3j55y04c62do1bpqku8k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3j55y04c62do1bpqku8k.png" alt="Card views"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Transitions
&lt;/h1&gt;

&lt;p&gt;Adding in a touch of animation on page load can really make your page pop.  I'm using the CDN from &lt;a href="//animate.style"&gt;animate.css&lt;/a&gt; to add an animation when the card enters the view for the first time by adding the classes &lt;code&gt;animate__animated animate__bounceIn&lt;/code&gt; to the card element&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gyazo.com/9102fdab826fc3594e1f374490136c3b" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.gyazo.com%2F9102fdab826fc3594e1f374490136c3b.gif" alt="Gif of animation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This may be a little intense, so look through their library and pick something more subtle &lt;/p&gt;

&lt;p&gt;Another option (I do not recommend doing both, as it will trigger the entrance animation when the mouse leaves the area) is to have the card pulse on hover.&lt;/p&gt;

&lt;p&gt;To do this, I had to extract a bit of code from the animate.css source &lt;a href="https://github.com/animate-css/animate.css/blob/main/source/attention_seekers/pulse.css" rel="noopener noreferrer"&gt;specifically here&lt;/a&gt; I then renamed their pulse class to &lt;code&gt;.hover-pulse:hover&lt;/code&gt; and applied the &lt;code&gt;animate__animated hover-pulse&lt;/code&gt; classes to my card.&lt;/p&gt;

&lt;p&gt;I stuck with just the entrance animation, the hover was a bit much.  &lt;/p&gt;

&lt;h1&gt;
  
  
  In conclusion
&lt;/h1&gt;

&lt;p&gt;WHEW, that was a lot of tinkering, but now I've got some nifty tricks to customize the rest of the app.  While I work on the other pages, what are some visual additions that could add some pop to this project?  &lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Customizing .NET's MVC template Part 1- The Dark Side</title>
      <dc:creator>Seth A Burleson</dc:creator>
      <pubDate>Fri, 30 Apr 2021 17:04:09 +0000</pubDate>
      <link>https://dev.to/sbrevolution5/customizing-net-s-mvc-template-part-1-the-dark-side-5doa</link>
      <guid>https://dev.to/sbrevolution5/customizing-net-s-mvc-template-part-1-the-dark-side-5doa</guid>
      <description>&lt;p&gt;So you're beginning to build .NET MVC apps, but the problem is, every time you open your webpage, its the boring black on white text that looks unprofessional and bland.  I've chronicled a couple tweaks to make the site look better using bootstrap classes and a little bit of css.  &lt;/p&gt;

&lt;h1&gt;
  
  
  The starting point
&lt;/h1&gt;

&lt;p&gt;As an example, We'll use my MoviePro app, specifically the index of movies.  Its basically a movie database with standard CRUD functionality.  It is currently only hosted locally, but in a few weeks I should have a more complete version online.  &lt;/p&gt;

&lt;p&gt;Right now, it looks very plain, like this: &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm31d4dm4udahvfk0gequ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm31d4dm4udahvfk0gequ.png" alt="Base version of moviepro"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, there's not much pleasant about the current design, but we're about to fix that.&lt;/p&gt;

&lt;h1&gt;
  
  
  The light, It burns me.....
&lt;/h1&gt;

&lt;p&gt;Lets try out some simple dark mode fixes for Bootstrap.&lt;/p&gt;

&lt;p&gt;First, lets apply a bg-dark class to the body tag.  Seems very simple, except that my scaffolded index page doesn't have a body tag.  It may seem that way, but really, the scaffolded index takes in the shared layout.  Check Views/Shared/_Layout.cshtml, and note that your specific view will be rendered within the main tag.&lt;br&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famb7lb9lrhir5t4qa6v7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Famb7lb9lrhir5t4qa6v7.png" alt="Rendered Body"&gt;&lt;/a&gt;&lt;br&gt;
All the code for your index view, and every other view for that matter, goes within this.  If you scroll to the top of the document, you'll see a body tag.  Add &lt;code&gt;class="bg-dark"&lt;/code&gt; to that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff07yslobshb6j0xn0hvj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff07yslobshb6j0xn0hvj.png" alt="Better but not by much"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oops, our navbar element stubbornly stayed dark, what we have to do here is make sure that the class is changed to &lt;code&gt;navbar-dark&lt;/code&gt; instead of light.  Probably a good idea to fix the &lt;code&gt;bg-white&lt;/code&gt; class at the same time, I'm going to use &lt;code&gt;bg-secondary&lt;/code&gt; to try and provide a little separation between my navbar and the body of the page. (you can do the same for the footer element with the &lt;code&gt;bg-secondary&lt;/code&gt; class, but you'll need to change the text color next step!)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgced09cacm1dx88a7d9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgced09cacm1dx88a7d9.png" alt="Nice and dark"&gt;&lt;/a&gt;&lt;br&gt;
Now its nice and dark but there's a major issue now.&lt;/p&gt;

&lt;h1&gt;
  
  
  How can I read that?
&lt;/h1&gt;

&lt;p&gt;Dark text on dark background is a MAJOR no no.  You can get away with dark text on the secondary background, but I think we should switch to a lighter text.  Let's do a simple find and replace on the shared layout changing &lt;code&gt;text-dark&lt;/code&gt; to &lt;code&gt;text-light&lt;/code&gt;.  That fixes the navbar, but not the body or footer.  The footer is at least in the same file so let's change the text-muted class to fix that. &lt;/p&gt;

&lt;p&gt;For the body, just add &lt;code&gt;text-light&lt;/code&gt; to your classes after &lt;code&gt;bg-dark&lt;/code&gt; Which should make things much more readable, except on your table.  for that, lets add a &lt;code&gt;table-dark&lt;/code&gt; class to each index.  &lt;/p&gt;

&lt;p&gt;The other thing I've done is changed my link color to a purple, specifically #6206EE for links which are also muted text (see part 2 for why) or links in a footer element, and #8D34FA for other links, which gave my links a bit of life compared to the default blue. I put this in my site.css:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F79d7265mnontn52d80y7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F79d7265mnontn52d80y7.png" alt="Sitecss"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This should leave you with a pleasing dark theme:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu93qgxtcyymmxsarw4vb.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu93qgxtcyymmxsarw4vb.jpg" alt="finished dark"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Bonus: Dark Inputs
&lt;/h1&gt;

&lt;p&gt;I made my input boxes dark by adding &lt;code&gt;bg-secondary text-light&lt;/code&gt; to my input and select elements on the create and edit pages.&lt;/p&gt;

&lt;p&gt;In the next installment we'll make a few UI changes, getting us away from the standard table to make things more modern.&lt;/p&gt;

&lt;p&gt;Cover image from unsplash.com &lt;/p&gt;

</description>
      <category>csharp</category>
      <category>css</category>
      <category>bootstrap</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Using LocalStorage to improve your webpage</title>
      <dc:creator>Seth A Burleson</dc:creator>
      <pubDate>Mon, 26 Apr 2021 01:55:44 +0000</pubDate>
      <link>https://dev.to/sbrevolution5/using-localstorage-to-improve-your-webpage-5782</link>
      <guid>https://dev.to/sbrevolution5/using-localstorage-to-improve-your-webpage-5782</guid>
      <description>&lt;p&gt;Localstorage is a simple way to save user data on your website, by letting them save it to their browser.  All it takes is a little JSON and you'll be on your way to a friendlier user experience.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Getting input
&lt;/h1&gt;

&lt;p&gt;Once you've got some input from a user via Form or browsing data, You'll need to save that to the browser.  Localstorage manages its storage based on a key value pair.  So take the array or object your data is stored in, assign it to a variable, and stringify it with JSON.  The save operation will look something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;localStorage.setItem("keyAsAString", JSON.stringify(myDataObjOrArray));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can decide when the localStorage should be updated, but generally, anytime the user resubmits a form or some kind of data, its a good idea to call this method again.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Retrieving values
&lt;/h1&gt;

&lt;p&gt;When the user comes back to the page, check local storage for the data. Make sure to parse it using JSON or you will just get a string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data = JSON.parse(localStorage.getItem("keyAsAString)) || []
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's very helpful to add a default if this fails, as I did in the above example. &lt;/p&gt;

&lt;p&gt;That's all there is to localstorage.  Where have you used this in a personal project?  &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>What is MVC?</title>
      <dc:creator>Seth A Burleson</dc:creator>
      <pubDate>Sun, 25 Apr 2021 18:28:05 +0000</pubDate>
      <link>https://dev.to/sbrevolution5/what-is-mvc-34af</link>
      <guid>https://dev.to/sbrevolution5/what-is-mvc-34af</guid>
      <description>&lt;p&gt;You've heard it all around the internet talking about programs,  MVC is a common topic.  Understanding this topic is key to progressing into more advanced web development and moving away from simple single page apps.  &lt;/p&gt;

&lt;h1&gt;
  
  
  What is MVC?
&lt;/h1&gt;

&lt;p&gt;MVC stands for &lt;strong&gt;Model View Controller&lt;/strong&gt; and describes the 3 components of your server-side web app.  It is different from a single page app not only because it runs on the server instead of the user's machine, but the code is generally a bit more organized as well.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Model
&lt;/h1&gt;

&lt;p&gt;The model holds that data used by the application.  Its usually defined by a class in object oriented languages like C# or Java, but it can be a database like MongoDB or SQLite.  Only one model is supplied per page, but it may have other models nested within, depending on what the page needs.&lt;/p&gt;

&lt;h1&gt;
  
  
  View
&lt;/h1&gt;

&lt;p&gt;The view is rendered on the server and returned to the user.  This is generally an HTML template filled with data (data which comes from the model) by the controller.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Controller
&lt;/h1&gt;

&lt;p&gt;The controller handles receiving requests from the user, performing logical operations, combining those with the model of the data, and returning the proper view to the user. &lt;/p&gt;

&lt;h1&gt;
  
  
  What are the advantages?
&lt;/h1&gt;

&lt;p&gt;The biggest advantage of MVC framework is the ability to separate logic between display logic and business/application logic.  This results in cleaner, more organized code that is not only easier to manage and navigate, but also easier to debug and improve.  Another advantage is security.  Separating your scripts from the visual part of the data can prevent malicious entities from interfering with your code.  &lt;/p&gt;

&lt;p&gt;How do you think about MVC frameworks?  What do you use to organize your code?&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>webdev</category>
      <category>html</category>
    </item>
  </channel>
</rss>
