Recently I was upgrading one of my projects from Visual Studio 2015 to Visual Studio 2017 (including converting from project.json and .xproj to .csproj), when I hit an error like this:

Microsoft.Common.CurrentVersion.targets(2867,5): error MSB3552: Resource file "**/*.resx" cannot be found.

It turns out this is caused by a long-standing MSBuild bug: Wildcard expansion is silently disabled when a wildcard includes a file over MAX_PATH. The Microsoft.NET.Sdk.DefaultItems.props file bundled with .NET Core includes a section that looks like this:

<EmbeddedResource 
  Include="**/*.resx" 
  Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)"
  Condition=" '$(EnableDefaultEmbeddedResourceItems)' == 'true' "
/>

When MSBuild tries to expand the **/*.resx wildcard, it hits this bug, resulting in the wildcard not being expanded properly. Some other MSBuild task interprets the **/*.resx as a literal file name, and crashes and burns as a result.

In my case, my build server was running an old version of npm, which is known to create extremely long file paths. The way to "fix" this is by reducing the nesting of your folders. If you're using npm, upgrading to a newer version (or switching to Yarn) should fix the issue. Otherwise, you may need to move your project to a different directory, such as a directory in the root of C:\.

Visual Studio 2015 was recently released, and with it came a newer beta of ASP.NET 5 (formerly referred to as "ASP.NET vNext"). ASP.NET 5 is a complete rewrite of ASP.NET, focusing on being lightweight, composible, and cross-platform. It also includes an alpha version of Entity Framework 7. However, EF7 is not yet production-ready and does not support all features of EF6. One feature that is missing from EF6 is support for other database providers - Only SQL Server and SQLite are supported at this time.

I wanted to transition a site over to ASP.NET 5, but needed to continue using MySQL as a data source. This meant getting Entity Framework 6 running on ASP.NET 5, which is pretty much undocumented right now. All the documentation and tutorials for EF6 heavily relies on configuration in Web.config, which no longer exists in ASP.NET 5. In this post I'll discuss the steps I needed to take to get it running. An example project containing all the code in this post can be found at https://github.com/Daniel15/EFExample.

Since EF6 does not support .NET Core, we need to remove .NET Core support (delete "dnxcore50": { } from project.json). Once that's done, install the EntityFramework and MySql.Data.Entity packages, and add references to System.Data and System.Configuration. For this post, I'll be using this basic model and DbContext, and assume you've already created your database in MySQL:

public class MyContext : DbContext
{
	public virtual DbSet<Post> Posts { get; set; }
}

public class Post
{
	public int Id { get; set; }
	public string Title { get; set; }
	public string Content { get; set; }
}

Entity Framework 6 relies on the provider and connection string being configured in Web.config. Since Web.config is no longer used with ASP.NET 5, we need to use code-based configuration to configure it instead. To do so, create a new class that inherits from DbConfiguration:

public class MyDbConfiguration : DbConfiguration
{
	public MyDbConfiguration()
	{
		// Attempt to register ADO.NET provider
		try {
			var dataSet = (DataSet)ConfigurationManager.GetSection("system.data");
			dataSet.Tables[0].Rows.Add(
				"MySQL Data Provider",
				".Net Framework Data Provider for MySQL",
				"MySql.Data.MySqlClient",
				typeof(MySqlClientFactory).AssemblyQualifiedName
			);
		}
		catch (ConstraintException)
		{
			// MySQL provider is already installed, just ignore the exception
		}

		// Register Entity Framework provider
		SetProviderServices("MySql.Data.MySqlClient", new MySqlProviderServices());
		SetDefaultConnectionFactory(new MySqlConnectionFactory());
	}
}

The first part of the configuration is a hack to register the ADO.NET provider at runtime, by dynamically adding a new configuration entry to the system.data section. The second part registers the Entity Framework provider. We also need to modify the configuration file to include the connection string. You can use any configuration provider supported by ASP.NET 5, I'm using config.json here because it's the default provider.

{
  "Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=localhost; Database=test; Uid=vmdev; Pwd=password;"
    }
  }
}

Now that we have the configuration, we need to modify the context to use it:

[DbConfigurationType(typeof(MyDbConfiguration))]
public class MyContext : DbContext
{
	public MyContext(IConfiguration config)
		: base(config.Get("Data:DefaultConnection:ConnectionString"))
	{
	}
	// ...
}

An instance of IConfiguration will be automatically passed in by ASP.NET 5's dependency injection system. The final step is to register MyContext in the dependency injection container, which is done in your Startup.cs file:

public void ConfigureServices(IServiceCollection services)
{
	// ...
	services.AddScoped<MyContext>();
}

AddScoped specifies that one context should be created per request, and the context will automatically be disposed once the request ends. Now that all the configuration is complete, we can use MyContext like we normally would:

public class HomeController : Controller
{
    private readonly MyContext _context;

    public HomeController(MyContext context)
    {
	    _context = context;
    }

    public IActionResult Index()
    {
        return View(_context.Posts);
    }
}

Hope you find this useful!

Until next time,
— Daniel

One of the most powerful features of ASP.NET MVC is its URL routing engine. The routing engine in ASP.NET MVC is used to route incoming requests to the correct controller action, but it can also generate URLs for you. This is normally done with the URL helper in views:

// Regular ASP.NET MVC:
@Url.Action("View", "Blog", new { id = 123 })
// With T4MVC:
@Url.Action(MVC.Blog.View(123))

This is great, as it means changing your routes will automatically update all the internal URLs throughout your site. If you're using T4MVC (which I strongly suggest), you also get compile time checking on your URLs, which means that it's literally impossible to have broken internal links (any invalid links will throw a compile error).

This is all well and good on the server side, but there's no equivalent on the client side, meaning that people often use one of these approaches:

  • Hard-code URL in JavaScript directly
  • Store the URL in a data attribute on the relevant element (or body)
  • Create a global JavaScript object containing all the URLs the page requires (for example, Jarret Meyer's approach)

Each of these approaches has its downsides. The last one is the most promising, and I had the idea of generalising this approach and making it into a library that can be dropped into any site. There are some existing projects that tackle this problem, the main one being Zack Owens' ASP.NET MVC JavaScript Routing. Zack's library looked good but I had two issues with it:

  • It's unnecessarily tightly coupled with jQuery, meaning you have to load the whole of jQuery just to use it, which is annoying if your site is just vanilla JavaScript or uses a library like PrototypeJS or MooTools instead.
  • It requires you to use a custom routing syntax rather than the standard ASP.NET MVC routing

I decided to write my own library to solve this problem. My library is called RouteJs, and it is available on NuGet. It supports ASP.NET MVC 2, 3 and 4. Basically, RouteJs consists of a small piece of JavaScript to handle building URLs, as well as some information about all the routes you want to expose. All of this is served using an ASP.NET handler, so you don't need to change your build scripts or anything like that. Simply drop it into your site.

Once loaded in your site, RouteJs provides a global Router object, similar to the URL helper that comes with ASP.NET MVC. For example, the same blog view URL can be generated with the following code:

var url = Router.action('Blog', 'View', { id = 123 });

It supports most of the common features of ASP.NET MVC routing, including areas, default values and simple constraints. It does not currently support ASP.NET WebAPI, but I'll definitely add support if someone requests it.

For more information, please see the readme on Github. Please let me know what you think!

Until next time,

— Daniel

The original release of ASP.NET MVC used HTML helpers with a syntax like the following:

@Html.TextArea("Title")

These worked, but if you renamed the property in your model (for example, from “Title” to “Subject”) and forgot to update your view, you wouldn’t catch this error until you actually tried out the page and noticed your model isn’t populating properly. By this time, you might have users using the site and wondering why stuff isn’t working.

ASP.NET MVC 2 introduced the concept of strongly-typed HtmlHelper extensions, and ASP.NET MVC 3 extended this even further. An example of a strongly typed HtmlHelper is the following:

@Html.TextAreaFor(post => post.Title)

These allow you to write more reliable code, as view compilation will fail if you change the field name in your model class but forget to change the field name in the view. If you use precompiled views, this error will be caught before deployment.

Creating your own

The built-in helpers are good, but quite often it’s nice to create your own helpers (for example, if you have your own custom controls like a star rating control or rich-text editor).

Read more ⇒

Well, back to posting coding-related blog posts, for now anyways 😛. Seeing as a lot of people seem to be confused by Object Oriented Programming, I thought I'd post a quick (or maybe not so quick) post about what OOP is, the main features, and how it can benefit you. This is paraphrased from an assignment I had on OOP last semester at university. I use C# code examples throughout this, but the concepts are very similar in other languages. Note that in this post, I assume you know the basics of programming, and just want to learn more about object orientation.

Now, let's begin looking at what OOP actually means. At its core, the Object Oriented paradigm consists of classes and objects. A class is a “thing” or entity that has a purpose, and an object is an instance of this entity. For example, a Car would be a class, and my car would be an object (instance of the Car class).

Read more ⇒