Set The Active Class On Bootstrap Nav Links In MVC

Here’s a quick way to set the active class on the current URL with a .Net MVC application.

1. Set a string variable equal to the request path at the top of the layout or view:

@{ 
    string path = Context.Request.Path;
}

2. Check the path variable against whatever the base url of the nav-link is. Add the “active” class if the path starts with your base path.

<a class="nav-link @(path.StartsWith("/robots") ? "active" : "")" href="/robots">Robots</a>

Now you will get the “active” highlight class on the correct nav-link when the current request matches the appropriate URL.

Redirect Umbraco 7

Redirect A Url To An External Domain In Umbraco 7

One of my clients has an Umbraco 7 site that pretty much takes care of itself other than a few minor content updates here and there. Today that client asked we set up a redirect from an internal URL to an external domain for their job postings. Normally this is an easy change using IIS rewrites in the web.config with the IIS Rewrite Module. But this site is hosted on GoDaddy and like all GoDaddy things, what I thought was easy turned out to be a bit more of a challenge.

After a bit of research I found you can redirect Umbraco URLs using the UrlRewritingNet component that’s built into Umbraco 7. Here’s an example of how to configure Umbraco 7 to redirect an internal URL to an external domain using the UrlRewriting.config config file.

To configure a URL rewrite open the configuration file located at /Config/UrlRewriting.config and add a rewrite rule like the example below. I found that rewriting to an external URL was more tricky than an internal virtual URL so here are a couple specifics to keep in mind when setting up a new rule for an external URL:

  1. Set rewriteOnlyVirtualUrls=”false” attribute inside <urlrewritingnet
  2. The virtualUrl is the source URL of the page you are redirecting from. The value in this attribute must start with http(s)://domain otherwise the rule will be ignored
  3. destinationUrl is the destination for the redirect
  4. redirect should be set to “Domain”

Here’s an example of the UrlRewriting.config file that will redirect an internal URL to an external domain.

<?xml version="1.0" encoding="utf-8"?>
<urlrewritingnet 
    xmlns="http://www.urlrewriting.net/schemas/config/2006/07"
    rewriteOnlyVirtualUrls="false"   >
    <rewrites>
        <add 
           name="redirectexample" 
           virtualUrl="https://example.com/jobs?$" 
           rewriteUrlParameter="ExcludeFromClientQueryString" 
           destinationUrl="https://clintmcmahon.com" 
           ignoreCase="true" 
           redirectMode="Permanent" 
           redirect="Domain" />
    </rewrites>
</urlrewritingnet>

 

There was an error running the selected code generator in .Net Core 5

I’m working on a new .Net Core 5 web app with user authentication where I need to customize some of the Identity account pages (Login, Register, Forgot Password, etc). Out of the box these pages are built into .Net Core so there’s nothing you need to do to use them. However, if you want to customize any of the account pages you’ll need to scaffold the source of those pages into your project.

To scaffold items in Visual Studio 2019 – (Version 16.8.4 as of today) right the project or parent folder then select “Add –> New Scaffolded Item”. This has worked for me in the past but recently in .Net Core 5 Visual Studio throws this error during the scaffolding process:

“There was an error running the selected code generator: ‘Package restored failed. Rolling back package changes for ‘Your App’.”

I found a workaround for this error by using the dotnet CLI outside of Visual Studio to execute the scaffolding tool. The following steps use the aspnet-codegenerator tool to scaffold the full Identity pages area into your .Net Core 5 app.

  1. Close Visual Studio.
  2. Open a command prompt and change directories to the project location.
  3. Make sure the aspnet-codegenerator tool is installed on your machine by executing this command:
    dotnet tool install -g dotnet-aspnet-codegenerator
  4. Add the Microsoft.VisualStudio.Web.CodeGeneration.Design package to the project if it does not already exist in your project:
    Install-Package Microsoft.VisualStudio.Web.CodeGeneration.Design
  5. Run the following command where MyApp.Models.ApplicationDbContext is the namespace to your DbContext:
    dotnet aspnet-codegenerator identity -dc MyApp.Models.ApplicationDbContext

If the command completed without errors that should have fixed the “There was an error running the selected code generator” issue and created the necessary Identity Pages under Areas/Identity/Pages.

MVC Scaffold Identity Pages

dotnet aspnet-codegenerator also has the ability to scaffold only specific files versus all the Identity files if you don’t need the full set by passing in the -files parameter followed by the files you want to create. (Thanks to Nick for giving me a heads up in the comments about this parameter).

dotnet aspnet-codegenerator identity -dc MyApp.Models.ApplicationDbContext –files “Account.Register;Account.Login;Account.Logout”

 

Convert A Generic List To CSV File In C#

This is an example of how to convert a generic list to a dynamic downloadable .csv file using C#, the CsvHelper library and the FileStreamResult.

Download the repo and run the full project solution from Github

In this example a request comes into the controller, we create a generic list of type ListItem, created a memory stream and using the CsvWriter library  return a dynamic .csv file to the browser.

Step 1: Create the generic list class
This class will hold our generic list items. This can be whatever data you need.

public class ListItem
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Step 2: Create the MVC action to return the CSV file
This action method creates the generic list, writes it to memory with help from the CsvHelper library and returns the FileStreamResult back to the browser.

//Action Method for your controller
[HttpPost]
public ActionResult ConvertToCSV()
{
    //Create the test list
    var list = new List<ListItem>()
    {
        new ListItem(){Id = 1, Name = "Jerry"},
        new ListItem(){Id = 2, Name="George"},
        new ListItem(){Id = 3, Name="Kramer"},
        new ListItem(){Id = 4, Name = "Elaine"}
     };

    byte[] result;
    using (var memoryStream = new MemoryStream())
    {
        using (var streamWriter = new StreamWriter(memoryStream))
        {
            using (var csvWriter = new CsvWriter(streamWriter))
            {
                csvWriter.WriteRecords(list);
                streamWriter.Flush();
                result = memoryStream.ToArray();
            }
         }
     }

     return new FileStreamResult(new MemoryStream(result), "text/csv") { FileDownloadName = "filename.csv" };
}

h/t to this StackOverflow post

Download the repo and run the full project solution from Github