CODE 5-2020 Web
CODE 5-2020 Web
SEP
OCT
2020
codemag.com - THE LEADING INDEPENDENT DEVELOPER MAGAZINE - US $ 8.95 Can $ 11.95
Full Steam
Ahead
Features
8 Progressive Web Apps (PWAs) 54 Deep Dive into ASP.NET Core
A
Somewhere between the simplicity of a website and the technological
complexity of a native app lives the progressive Web application.
Localization
PWAs are built with browser-based technologies but can act just like Joydip shows you how to take advantage of internationalization
a native app. Sahil shows you how. in ASP.NET Core to enable a broader reach for your applications.
Sahil Malik Joydip Kanjilal
US subscriptions are US $29.99 for one year. Subscriptions outside the US pay $49.99 USD. Payments should be made in US dollars drawn on a US bank. American Express,
MasterCard, Visa, and Discover credit cards are accepted. Bill Me option is available only for US subscriptions. Back issues are available. For subscription information,
send e-mail to [email protected] or contact Customer Service at 832-717-4445 ext. 9.
Subscribe online at www.codemag.com
CODE Component Developer Magazine (ISSN # 1547-5166) is published bimonthly by EPS Software Corporation, 6605 Cypresswood Drive, Suite 425, Spring, TX 77379 U.S.A.
POSTMASTER: Send address changes to CODE Component Developer Magazine, 6605 Cypresswood Drive, Suite 425, Spring, TX 77379 U.S.A.
been rescheduled is Prairie DevCon in Winnipeg. Over the last 30 years, I’ve used the following Python: Python is probably the most challenging
The cancellation of this conference has a real tools first as a beginner then in many (but not and interesting of the tools I’m exploring. Python
sting for me, as this conference is where I would all) cases as a master: dBase, FoxBase+, FoxPro, is firmly entrenched in the Data Science world.
have given my first keynote speech. Visual Basic, Visual FoxPro, SQL Server, HTML/ If you plan on working in this world, you’ll need
CSS/JavaScript, Ruby, Ruby on Rails, Visual Basic at least a minimum exposure to Python. I recom-
My keynote was entitled “Just Your Every Day .NET, C#, and my newest addition: Python. These mend checking out the Python content at CODE
Ordinary Programmer” (title borrowed from Joe are just the languages, there are numerous add- Magazine (www.codemag.com) that we’ve devel-
Walsh, Thanks Joe!). In this keynote I would ons, IDEs, frameworks, and operating systems oped over the years. Many of these articles are
have talked about 30+ years as a developer and that I also throw into the mix. targeted at people leveraging knowledge of one
regaled with many stories. I’d have stressed how, technology to learn some new technology.
even after 30 years, there’s still new stuff to While we are under work-from-home orders and
learn—it took this long to get to my first keynote, required to limit our participation in social gath- These are just a few items I’ve been spending
for instance—and that’s my favorite part of being erings, it might be a good time to consider be- time with (including ample time to perfect that
a developer: The Joy of Being a Beginner. coming a “beginner” in a new technology. cancelled keynote, LOL). I know that these times
are rough for people mentally and you may not
I listen to several podcasts and one of my favor- I’ve been working at home for a bit over two de- have the bandwidth or desire to learn new tech-
ites is called ScriptNotes. ScriptNotes is hosted cades, so that part’s not new. What is new is the nologies. But if you are so inclined, let’s commu-
by John August and Craig Mazin, two fabulous lack of social events that I participate in to for a nicate about what we’re learning. I love hearing
working screenwriters. On Episode 439, “How to “change of scenery.” No Dungeons & Dragons (we from readers, so if you’d like to share I’m @rod-
Grow Old as a Writer,” John and Craig discussed play online now), no concerts, no movies out, no paddock on Twitter, I hope to hear your experi-
extensively about how each medium you write for poker games, no eating out at restaurants. Just ences being a beginner again.
has its own unique qualities. John (who write the like you, I now have a lot of free time on my
film Big Fish) made the following comment: hands. I’m taking this time to add new technolo-
gies to my mix. Here are some of the technologies Rod Paddock
I am exploring.
“Big Fish (the musical) gave me .NET Core (and ASP.NET Core): I came to .NET
Core a bit late in my development cycle. My com-
a chance to be a beginner again. pany has many websites built in the 4.x frame-
To be someone who is brand work, so I’ve had little time to use ASP.NET Core
new to things and be curious previously. Now, I’ve started a new business ven-
ture and we’ve built out our new platform using
and eager to explore and ASP.NET Core. Also, I’m a bit fascinated by the
willing to make mistakes as I’m idea of building single-file executables.
figuring out this new art form. Docker: Docker is a newfangled way of deploy-
When you have mastery over ing and running applications. I’m still a neophyte
something, it’s nice, it’s helpful, when it comes to Docker, which makes it all the
more fun. The idea of building a single-file ap-
things are easier for you, plication using .NET Core and deploying it using
but they’re also less exciting.” Docker is a fun area I am exploring.
6 Editorial codemag.com
NEVRON OPEN VISION (NOV)
The future of .NET UI development is here
Whenever Apple releases a new iOS version, with a signifi- proxy written in JavaScript between your app and the out-
cant new capability that’s locked to new kinds of applica- side world. It can give you a lot of fine control on your net-
tions, I may look at it out of a curiosity perspective. But, work requests. This means that you can control the cach-
the process of downloading, installing, and then cleaning ing behavior of individual components of your Web page or
applications is just tedious. I think the most commonly used website. This gives you a lot of control on what gets loaded
app on my phone is the browser. and what doesn’t. For example, you can decide that large
JavaScript files are loaded only on demand, and they are
However, browser-based applications, or let’s call them cached. This means that when the user revisits your Web
websites, have significant limitations. On the other hand, page or goes from page to page within the same website,
Sahil Malik native apps that get installed on your device are a hassle to the files are not constantly reloaded. This is not so great for
www.winsmarts.com install, manage etc. Progressive Web applications are some- complex pages that you want to load faster.
@sahilmalik where in the middle. They are built using browser-based
technologies, but they can act and be installed as a native
Sahil Malik is a Microsoft
app. They can be installed directly from your browser, or
MVP, INETA speaker,
a .NET author, consultant,
even distributed through the App Store. Realistically speak- A service worker is a client-side
ing, although they can work offline, do interesting things
and trainer.
like offline storage, work with your camera, do geolocation,
programmable proxy written in
Sahil loves interacting with and typically do things that are reserved for a native ap- JavaScript between your app and
fellow geeks in real time. plication, a native app will still win when it comes to those the outside world.
His talks and trainings are capabilities. Progressive Web apps give you the incredible
full of humor and practical convenience of being installable right through the browser
nuggets. or App Store, if you choose, and they are built using stan-
dard Web-based technologies that we’re already familiar Additionally, service workers also enable you to handle push
His areas of expertise are with. And although progressive Web applications may not messaging. A service worker is nothing but a type of a Web
cross-platform Mobile app scale to the capabilities of a native application, a vast num- worker. It’s a JavaScript file that runs separately from the
development, Microsoft ber of applications don’t need those capabilities. main browser thread. It intercepts network requests, caches
anything, and security or retrieves resources from the cache, and can deliver push
and identity. In fact, you’d be surprised to know how many applica- messages to you.
tions in app stores today are actually progressive Web apps
(PWAs). In this article, I intend to explain what PWAs are, The key here is that the service worker runs separately from
their capabilities, and their limitations. the main thread. This means that service workers are inde-
pendent of the application they are associated with. This
Before I get started, let me let you in on a little secret: Even means that they’re a lot more powerful than the traditional
if you never intend to write a mobile application, the con- caching techniques that you’ve used in the applications
cepts presented in this article are applicable to you as a Web you’ve used so far. Another consequence of the service
developer. The amazing thing about PWAs is that they sim- worker running separately from the main thread is that it
ply use Web-based technologies that you’re already familiar can receive push notifications even when the app isn’t run-
with. For example, one of the core technologies of PWAs ning in the browser.
is service worker. Service worker, when applied to any Web
application, can greatly improve the load times of your Web Service worker APIs are also designed to be fully asynchro-
pages. Research after research has shown that users prefer nous; this means that synchronous APIs, such as localStor-
to use fast loading Web pages. In fact, if your Web page age, are inaccessible from service workers directly. Addi-
takes more than three seconds to load, that might be a lost tionally, they must work only on HTTPS. A service worker
customer. That’s just one of the things a PWA can do for you. can’t access the DOM directly, but must work through the
I was amazed to open my developer tools on my browser and postMessage method to send data and a message to an
see how many applications already use these technologies. event listener to receive data.
Without further ado, let’s get familiarized with core building As you can imagine, service workers, given their nature of
block of PWAs, the service worker. being able to run independent of the application itself,
open doors to some amazing capabilities. Some of these ca-
pabilities are offline; first application pattern and leverag-
Service Worker ing caching, a Notifications API that allows your application
Sometimes, it’s hard to be a worker in the IT industry. For to interact with the operating system’s notification system,
example, if I were to use the words “service worker” at a a push API that lets your app subscribe to a push service
party, what would people think? So, before anyone casts of any kind, a background sync API that lets the user defer
any aspersions, let’s go ahead and define what a service actions until better network connectivity is available, and a
worker is. A service worker is a client-side programmable channel messaging API that service workers communicate
Notifications API
The Notifications API allows your Web application to push
notifications to the user by taking advantage of the operat- Figure 1: The Notifications API requesting permission.
ing system’s notifications capabilities. You may have noticed
that on any modern operating system, applications can re-
quest to send you notifications when something of interest serviceWorkerRegistration
appears for you. These notifications can then be centrally .pushManager
managed in control panel, system preferences, settings etc. .subscribe(options).then(
Wouldn’t it be nice if a Web application could send such no- function(pushSubscription) {
tifications as well? Of course, this needs the user’s permis- // use the subscription
sion. That’s exactly the job of the Notifications API. You’ll });
be pleased to know that using the Notifications API is really
simple. Here is how you use the Notifications API. Background Sync API
The background sync API allows you to defer actions until
let promise = the user has stable connectivity. As you can imagine, this is SPONSORED SIDEBAR:
Notification.requestPermission(); critical for occasionally online applications. Remember that Are Your Legacy Apps
in a lot of places in the world, there isn’t reliable or good Stuck in the Past?
Notice that a lot of these APIs rely on a promise-based Internet connectivity. This isn’t a binary one or zero, as in
mechanism. This is because these APIs are designed to be being online or offline. Sometimes when you have poor con- Need FREE advice on
asynchronous. For example, the Notifications API returns a nectivity, you want to pull the phone out of your pocket, migrating yesterday’s
promise, which then waits for the user to either allow or dis- take a picture, and put it back in your pocket. Later when legacy applications
allow sending notifications. This dialog asking for permis- you have better connectivity, you can perhaps upload that to a today’s modern
sion is specific to the operating system and browser you’re picture. This is exactly what the background sync API lets platforms? Get answers
on, but on Mac and Safari, it looks like Figure 1. you do. by taking advantage of
CODE Consulting’s years
The Notifications API comes with a rich set of methods and Just like many other APIs, the background sync API also relies of experience migrating
properties that let you do the various things you’d expect on service workers. It uses a service worker as an event tar- legacy applications by
from a first-class notification infrastructure. For example, it get, which allows it to work in a background mode when the contacting us today to
lets you check whether the user has granted a permission Web page isn’t open. You use it in two steps: First you register schedule your free hour of
CODE consulting call with
or not. It lets you craft up a notification and it lets you your service worker and listen for sync events from a page,
our expert consultants.
show the notification. It then gives you the various events and second you listen to the event in your service worker.
No strings. No commitment.
necessary to handle the notification, for example whether For more information,
it’s visible, whether it has been dismissed etc. In scenarios To register, you use this code: visit www.codemag.com/
where the user hasn’t granted permissions for notifications, consulting or email us at
you can re ask the user to grant such a permission, or simply navigator.serviceWorker [email protected].
show an alert box or some other mechanism for communi- .register('/mysw.js');
cating with the user.
Once registered, you can then request for a sync:
Push API
The push API allows your application to receive messages navigator.serviceWorker.ready.then(
pushed to it from the Web server. Note that this is differ- function(registration) {
ent from your standard Ajax calls. The push API allows your return registration.sync.register(
application to receive messages when the application isn’t syncEvent');
even loaded. The push API works hand-in-hand with the });
Notifications API; for example, a pushed message can be
shown as a notification. Later, when there’s a sync event matching the phrase “sync
Event”, you can act upon it in your mysw.js file as shown
For your application to receive push messages, it must have here:
an active service worker. When the service worker is active,
you simply subscribe to push notifications using the below self.addEventListener('sync',
code snippet: function(event) {
if (event.tag == 'syncEvent') {
let promise = PushManager.subscribe(); event.waitUntil(doStuff());
}
This gives you a PushSubscription object, which has all });
the information, such as the subscription URLs endpoint,
expiration time of the push subscription, etc. Realistically The doStuff method returns a promise and that’s where you
speaking, to use the push manager, you’ll always need a can work on the actual task. If the promise fails, another
service worker. So once you have a service worker registra- sync is automatically scheduled for you. Retry sync waits for
tion, your code will look like this: connectivity and also uses exponential back off.
app.use(express.static(__dirname));
Listing 4: Caching files after installation And here is where NodeJS-specific stuff ends. You can re-
place everything I talked about here so far with any Web
const filesToCache = [ server you wish. Now let’s focus on the PWA parts that are
'/',
'index.html' entirely client side.
];
Now go ahead and place an index.html and sw.js file in the
const staticCacheName = 'mycache';
same folder. The index.js file is where the simple application
self.addEventListener('install', event => { will live, and the sw.js file is where the service worker will
console.log('Installing service worker'); live.
event.waitUntil(
caches.open(staticCacheName)
.then(cache => { In the index.html file, go ahead and place the code, as
console.log('Caching file'); shown in Listing 3.
return cache.addAll(filesToCache);
}) if you pay close attention to Listing 3, the HTML page has
);
}); a simple message. It says, “My awesome page.” However,
there’s an interesting JavaScript snippet there that regis-
ters a service worker. The service worker is defined in the
Listing 5: Serving files from the cache sw.js file.
self.addEventListener('fetch', event => {
console.log('Fetch event for ', event.request.url); In sw.js file, you do two things. First, you listen to the in-
event.respondWith( stall event. Once the service worker has installed, you cache
caches.match(event.request) the files that are of interest to you. These files are cached
.then(response => { because later, they’ll allow the application to work offline.
if (response) {
console.log( In this case, you intend to cache only the index.html file,
'Found ', event.request.url, ' in cache'); which is the only file in your project. You can, of course,
return response; extrapolate this to other scenarios. This code can be seen
}
console.log(
in Listing 4.
'Network request for ', event.request.url);
return fetch(event.request) Now that the files are cached, the next thing you do in
}).catch(error => { the service worker is listen to the fetch event. In the fetch
console.log('Error, ', error);
}) event, if the file is available in the cache, you simply serve it
); from the cache. This saves a server roundtrip, and it allows
}); the application to work offline. The code for this can be seen
in Listing 5.
node server.js
Once the server is running, open your browser and visit loc-
alhost:8000. I’ll use chrome, but really any browser that lets
you debug service workers will do. Your page should load as
shown in Figure 2
At this point, Chrome is practically offline. Now go ahead My point is that you don’t have to go full-blown PWA to
and hit refresh on the page. What do you notice? You’ll see start taking advantage of the involved technologies. I must
that the page loads just as expected, except that the net- also confess that this article is at a very beginner level for
work call never made it to the Web server. You can verify PWAs. There’s a lot more to learn: there are concepts, such
that by setting a breakpoint in server.js, and the breakpoint as how to design your applications in a responsive manner;
won’t get hit. This is great, because now the application is there are tools available, such as lighthouse, that allow you
working offline. It’s working because the service worker has to analyze your PWAs; there are concepts around debugging
intercepted the request and is serving index.html from its your PWAs; and then there are many other APIs, such as
local cache. This is how the world’s simplest PWA is built. credential management API etc., that I didn’t even get to
touch upon.
Summary In my future articles, I hope to talk more about such addi-
Let me be honest here, PWA is a groundbreaking technol- tional aspects of PWAs. Until then, happy coding.
ogy. If you examine your Chrome developer tools, under the
application tab, under service worker, you’ll be amazed to Sahil Malik
see how many websites you commonly visit are already mak-
With the product table from the AdventureWorksLT data- the IProductRepository.cs interface class and add a new
base, you created a page to display product data in an HTML method stub. This method accepts a single integer value for
table. In addition, you wrote code to search for products the primary key of the product to retrieve.
based on user input.
Product Get(int id);
In this final part of this article series, you build a product
detail page to add and edit product data. You add a delete Next, open the ProductRepository.cs class and add a new
button on the list page to remove a product from the data- method to implement the Get(id) method in the interface.
Paul D. Sheriff base. You learn to validate product data and display valida- The code for this method uses the LINQ FirstOrDefault()
http://www.pdsa.com tion messages to the user. Finally, you learn to cancel out of method to locate the product ID in the product table. If
an add or edit page, bypassing validation and returning to the value is found, a Product object is returned from this
Paul has been in the IT the product list page. method. If the value is not found, a null value is returned.
industry over 33 years.
In that time, he has suc- public Product Get(int id)
cessfully assisted hundreds Create Product Detail Page {
of companies to architect
At some point, your user will want to add or edit the details return DbContext.Products.FirstOrDefault(
software applications to
of one product. Because they can’t see all the product fields p => p.ProductID == id);
solve their toughest business
problems. Paul has been on the list page, create a detail page as shown in Figure 1. }
a teacher and mentor Add a new partial page named _ProductDetail.cshtml under
through various mediums the \Views\Product folder. In this new partial page, add the Modify the View Model Classes
such as video courses, code shown in Listing 1. Two new properties need to be added to your view model
blogs, articles, and speaking classes to support adding or editing a single product object.
engagements at user To get to the new product detail page, add an Edit button in First, open the ViewModelBase.cs class and add a Boolean
groups and conferences each row of the product table. Open the _ProductList.cshtml value to tell the view to display the detail page you just
around the world. partial page and add a new table header element before the added.
Paul has 23 courses in the other <th> elements in the <thead> area.
www.pluralsight.com library public bool IsDetailVisible { get; set; }
(http://www.pluralsight. <th>
com/author/paul-sheriff) Edit Next, open the ProductViewModel.cs class and add a new
on topics ranging from </th> property to hold the instance of the product class returned
JavaScript, Angular, MVC, from the Get(id) method in the repository class.
WPF, XML, jQuery, and Within the <tbody> area, add a new table detail element before
Bootstrap. Contact Paul all the other <td> elements, as shown below. Notice the two public Product SelectedProduct { get; set; }
at [email protected]. data- attributes that are added to the anchor tag. The data-
custom-cmd attribute has a value of “edit,” which is sent to the The product ID is posted back from the view to the view
view model to place the user into edit mode. The second attri- model class using the EventArgument property. Add a new
bute, data-custom-arg, is filled in with the primary key value of method named LoadProduct() to which you pass this prod-
the product to edit. This key value is used by the Entity Frame- uct ID. This method calls the new Get(id) method in the
work to lookup the details of the product and fill in a single Repository class to retrieve the product selected by the user.
product object to which the product detail page is bound.
protected virtual void LoadProduct(int id) {
<td> if (Repository == null) {
<a href="#" throw new ApplicationException(
data-custom-cmd="edit" "Must set the Repository property.");
data-custom-arg="@item.ProductID" } else {
class="btn btn-primary"> SelectedProduct = Repository.Get(id);
Edit }
</a> }
</td>
Remember that in the controller class, the HandleRequest()
Modify Repository method is always called from the post back method. In this
To retrieve a single product object based on the primary key method, add a new case statement to check for the “edit”
value, add a new method to your repository classes. Open command passed in via the data-custom-cmd attribute. Call
case "edit":
LoadProduct(Convert.ToInt32(EventArgument));
IsDetailVisible = (SelectedProduct != null);
break;
<input type="hidden"
asp-for="IsDetailVisible" />
<form method="post">
<partial name="~/Views/Shared/
_StandardViewModelHidden.cshtml" />
@if (Model.IsDetailVisible) {
<partial name="_ProductDetail"
for="SelectedProduct" />
}
else {
<partial name="_ProductSearch.cshtml" />
<partial name="_ProductList" />
}
</form>
Try It Out
Now that you’ve created the detail page and added the appro-
priate properties to the view model, it’s time to see the detail
data. Run the application and click on an Edit button in your
product list. If you’ve done everything correctly, you should be
taken to the detail page and the product’s data should appear.
Figure 1: The product detail page allows you to add or edit data.
Using Data Annotations
When you ask a user to input data, you must ensure that
they enter the correct values. Typically, you want to validate When you first created the Product class, you added a few
the user’s input both on the client-side and the server-side. data annotations, such as [DataType] and [Column]. These
Use client-side validation to make the Web page responsive annotations help MVC map the data coming from the da-
and eliminate the need for a round-trip to the server just tabase table to the appropriate properties. They also tell
to check business rules. Use server-side validation to en- MVC what data type to put into the <input> element for the
sure that the user didn’t bypass the client-side validation by bound property. In addition, they help validate the values
turning off JavaScript. posted back by the user.
Listing 1: The product detail page lets your user see all of the fields to add or edit.
@model MVVMEntityLayer.Product <label asp-for="Weight" class="control-label"></label>
<input asp-for="Weight" class="form-control" />
<input asp-for="ProductID" type="hidden" /> </div>
<div class="form-group"> <div class="form-group">
<label asp-for="Name" class="control-label"></label> <label asp-for="SellStartDate" class="control-label">
<input asp-for="Name" class="form-control" /> </label>
</div> <input asp-for="SellStartDate" class="form-control" />
<div class="form-group"> </div>
<label asp-for="ProductNumber" class="control-label"> <div class="form-group">
</label> <label asp-for="SellEndDate" class="control-label">
<input asp-for="ProductNumber" class="form-control" /> </label>
</div> <input asp-for="SellEndDate" class="form-control" />
<div class="form-group"> </div>
<label asp-for="Color" class="control-label"></label> <div class="form-group">
<input asp-for="Color" class="form-control" /> <label asp-for="DiscontinuedDate"
</div> class="control-label">
<div class="form-group"> </label>
<label asp-for="StandardCost" class="control-label"> <input asp-for="DiscontinuedDate"
</label> class="form-control" />
<input asp-for="StandardCost" class="form-control" /> </div>
</div> <div class="form-group">
<div class="form-group"> <button data-custom-cmd="save"
<label asp-for="ListPrice" class="control-label"> class="btn btn-primary">
</label> Save
<input asp-for="ListPrice" class="form-control" /> </button>
</div> <button formnovalidate="formnovalidate"
<div class="form-group"> class="btn btn-info">
<label asp-for="Size" class="control-label"></label> Cancel
<input asp-for="Size" class="form-control" /> </button>
</div> </div>
<div class="form-group">
<div asp-validation-summary="All"
class="text-danger">
</div>
@section Scripts
{
<partial name="_ValidationScriptsPartial"/>
<script>
Figure 2: The validation error messages can be displayed all in one area if you desire.
…
</script>
}
Try It Out
Run the application and click on the Edit button next to one
of the products. Delete the data in the Product Name field.
Set the Cost and the Price fields to a value of minus one (-1)
and click on the Save button. You should now see the error
messages appear at the top of the page just like that shown
in Figure 2.
<div class="form-group">
<label asp-for="Name"
class="control-label"></label>
<input asp-for="Name"
class="form-control" />
<span asp-validation-for="Name"
class="text-danger" />
</div>
<span asp-validation-for="ProductNumber"
class="text-danger" />
<span asp-validation-for="Color" Figure 3: The validation error messages can be displayed near each field in error.
Instantly Search
return View(vm); the issue and article, or by
}
visiting www.pdsa.com/
downloads. Select “Fairway/
Try It Out
Run the application and click the Edit button on any product
PDSA Articles” from the
Category drop-down.
Then select “Use the MVVM
Terabytes
in the list. Click the Cancel button and you should be taken Design Pattern in MVC Core -
back to the list of products. Part 3” from the Item drop-down.
Open the _ProductSearch.cshtml file and create the Add Open the ProductViewModel.cs file and add a Save() meth-
button immediately after the Search button. od. The Save() method checks the value in the ProductID
property of the Product object to see if it’s null or not. If
<button type="button" class="btn btn-info" it isn’t null, you’re editing a product and thus you call the
data-custom-cmd="add"> Update() method on the Repository object. If the ProductID
Add New Product property is a null, then it’s a new product object and you call
</button> the Add() method on the Repository object.
return true;
}
programmers at Microsoft make their living now. To some, patent-based lawsuits around software between the various
it may appear that this move to open-source development software players in the 1980s and 90s until eventually, the
started back at the Build conference in 2014. That was the cross-licensing of patents between the companies became
day that Anders Heljsberg took the stage during the keynote normal.
to publish the Roslyn compiler on GitHub as an open-source,
cross-platform tool. Or perhaps it started in the fall of 2014 Building software that ran on many microcomputers was
with the announcement of.NET Core. But those events were an early strategy at Microsoft, and it expanded when they
hardly the beginning, although you could consider those moved into the operating system business, first with MS-
events as the “end of the beginning” of a new Microsoft, A DOS and ultimately with Windows. When combined with the
Richard Campbell Microsoft that embraced open source. IBM PC architecture that allowed multiple hardware manu-
@richcampbell facturers to make compatible PCs, Microsoft grew to domi-
http://historyofdot.net/ Going back to the actual beginning of Microsoft in 1976, nate the microcomputer market by the end of the 1990s
richard@campbellassoci- when Bill Gates and Paul Allen created the company, Bill had with operating systems and development tools.
ates.ca a great insight into the future of software. In those days,
Richard Campbell wrote his software, at least software for the early microcomputers, Microsoft wasn’t the only beneficiary of its dominance; a
first line of code in 1977. was almost entirely free. It was also unique to the particular vast ecosystem of vendors and independent developers
His career has spanned microcomputer: Each new microcomputer needed new pro- made their living building software and products for Win-
the computing industry grams. The sharing of code was common. dows.
both on the hardware and
software sides, develop- In that period of rapid innovation of microcomputers, com- The dominance in the marketplace came with consequences
ment and operations. panies often competed with their own earlier products or also, ultimately leading to a court case brought by the U.S.
He was a co-founder of announced new products so early that it sabotaged existing Department of Justice around monopolistic behavior at
Strangeloop Networks, ac- sales. The lack of software was a constant problem, and de- Microsoft. By November of 1999, Judge Jackson declared
quired by Radware in 2013 velopers had to pick their favorite hardware to develop for, Microsoft a “predatory monopoly.” The judge ordered the
and was on the board of only to have the company make a new computer that the old company broken into two: One company would be an op-
directors of Telerik that was software wouldn’t run on—or go broke. erating system company and the other company would be
acquired by Progress Soft- everything else.
ware in 2014. Today he is a Bill Gates saw the need for software to be a product unto
consultant and advisor to itself, especially software that could be coded once and ex- The breakup never happened. In January 2000, Steve
several successful technol- ecuted on a variety of computers. In 1976, he wrote an open Ballmer took over as CEO of Microsoft, Bill Gates stayed on
ogy firms and is the founder
letter to the hobbyists at the Homebrew Computer Club, en- as chairman of the board and also moved into a chief ar-
and chairman of Humanitar-
couraging them to stop sharing software, specifically com- chitect role, overseeing all of the products that Microsoft
ian Toolbox (www.htbox.
org), a public charity that
mercial software. In the letter, he pointed out that if no one made. Steve’s first mission as CEO was to keep the company
builds open-source software can make a living from software, why would anyone go to together, and as we know, he succeeded, resulting in the
for disaster relief. Richard the effort to write and maintain it? consent decree with the US government in November 2001.
is also the host of two
podcasts: .NET Rocks! The idea of retail software in microcomputers was novel, and Part of that consent decree included Microsoft being more
(www.dotnetrocks.com) the it required legal protection. The protection came in the form open about its source code. Some of the complaints from
Internet Audio Talkshow for of the End User License Agreement (EULA), which changed the industry around Microsoft that led to the DOJ court
.NET developers and RunAs the definition of ownership of software: You never actually case had included concerns that Windows was hostile to
Radio (www.runasradio.com), own software, just a limited license to use it. Included in some third-party software. Although there was never any
a weekly show for IT Profes- those limits is protection for the developer for liability. Any evidence of this being true, Microsoft, as part of the con-
sionals. He also produces compensation for harm caused by the software is limited to sent decree, did agree to share part of the source code of
the DevIntersection the price of the software, typically. Windows with these third-party companies so that they
(www.devintersection.com) could better understand how Windows interacted with their
series of conferences. With software as the business and protection in the form of software.
the EULA, commercial software for microcomputers snow-
balled, and Microsoft was one of the leading companies Was this open source? Far from it. It was shared source, and
making software manufacture into their business and stay- that sharing took place under specific circumstances.
ing (for the most part) out of the hardware business.
It was into this world that .NET was born. Steve Ballmer
As a developer at Microsoft, you not only wrote proprietary announced the development of .NET the PDC conference in
closed-source software that the company sold but also filed 2000. Steve talked about .NET at the keynote as “a new plat-
patents for any innovative aspects of the software. The num- form based on Internet Standards.” He also announced the
ber of patents you secured around your code affected how publication of the C# specification and the Common Lan-
much Microsoft paid you. The creation of software patents guage Infrastructure as ECMA specifications. It’s important
is part of a broader “IP-Moat” strategy that led to numerous to remember that this was in the middle of the consent de-
Those ECMA specifications would inspire a young man by the Also announced at Mix06 was Internet Explorer 7 almost
name of Miguel de Icaza. Reading those specifications, he five years after Microsoft shipped Internet Explorer 6 and
decided that he liked C# and the whole concept of .NET. In WPF/E, or Windows Presentation Foundation Everywhere,
July of 2001 at an O’Reilly Conference, he announced the which would eventually be known as Silverlight. The first
development of Mono: An Open-Source implementation of CTP of Silverlight would ship in December 2006.
.NET for Linux.
In 2007, the energy around open source and Microsoft
It’s interesting to note that the month before (June 2001), technologies peaked with several different fronts opening
Steve Ballmer said in a newspaper article that “Linux is a at once. The first was ASP.NET MVC, based on the Model-
cancer.” He would, much later (2016), change his position View-Controller software design pattern. Built to address
on that statement. the challenges of ASP.NET WebForms, MVC would also work
alongside WebForms while offering a more maintainable ap-
Microsoft continued opening up its source code around .NET proach to Web development.
in 2002 with the release of the Shared Source Common Lan-
guage Infrastructure that was code-named “Rotor.” Rotor The next front in open-source at Microsoft was a movement
included the .NET Runtime, base class libraries, and a C# of open source-minded .NET developers, a group that would
compiler, but removed all the Windows-centric technolo- eventually be known as ALT.NET. At the time, a lot of devel-
gies. opers building on the Microsoft stack didn’t consider open-
source libraries or tools at all. That point of view existed
Rotor had what Microsoft called an “academic research li- within Microsoft as well: Perhaps a form of Not-Invented-
cense,” so it wasn’t open source—more like source open. Here syndrome, Microsoft tended to build tools for devel-
Anyone with academic credentials could request a copy, so opers even when there were excellent open source tools
Rotor was more broadly available than the source code for available.
Windows. Academics were only able to read the .NET code to
understand behavior. There wasn’t any way to compile the The final front comes in the fall of 2007, Scott Guthrie began
code for .NET or to use it in an application directly. recruiting folks like Scott Hanselman, Phil Haack, and Rob
Conery—all people with strong backgrounds in open source
The open-source story of .NET goes quiet for a few years technologies (some people would call them “Scott Guthrie’s
after the release of Rotor, but .NET itself evolved rapidly, Ninja Army”). On Phil Haack’s blog at the time, he men-
releasing 1.0 in February of 2002, 1.1 in April of 2003, and tioned seeing a product that inspired him to want to be part
2.0 in November of 2005. Microsoft was doing its best to be of Microsoft. That technology was the prototype of MVC.
a more open company with the advent of things like Channel
9, presenting the face of the developers at Microsoft who All of these fronts came together in October of 2007 at the
built products like .NET. Another aspect of openness was the ALT.NET Open Space Conference in Austin. Scott Guthrie had
willingness to show off the earliest bits of its next operating been invited to keynote at the conference and surprised
system, code-named Longhorn, although one could argue the attendees with the first public demonstration of ASP.
that they showed those bits off a bit too soon. NET MVC. He also announced that ASP.NET MVC would be an
open-source project published on CodePlex.
By 2006, .NET 2.0 was a relatively mature product, and de-
velopers had built large applications in ASP.NET WebForms. At the same time, Microsoft announced that the .NET Frame-
There were challenges around the maintainability of Web- work 3.5 libraries would be available under the Microsoft
Forms: The architecture of WebForms had focused on making Reference Source License (MS-RSL). The MS-RSL opened up
Web development feel like WinForms development, hiding the source code of the .NET Framework to anyone who want-
a lot of the metaphors of Web development. It was easy to ed to look at it, so in that sense, it was an expansion of the
learn and code in, but creating maintainable and testable Rotor project back in 2002 that was for academics only. Still,
Web applications was very difficult. the MS-RSL wasn’t making the .NET Framework open-source;
the primary purpose of the Reference Source was to help in
In the same time frame, David Heinemeier Hansson (DHH) debugging applications built with .NET.
was developing Ruby on Rails, first released as an open-
source project in July of 2004. Developers fell in love with The development of ASP.NET MVC did not take place directly
the Ruby on Rails approach to building Web applications, on CodePlex. The developers at Microsoft working on MVC
with lots of built-in automated testing and rapid develop- wrote code into internal source control, build, and test sys-
ment features. tems. Periodically, a version of ASP.NET MVC was published
to CodePlex for the public to explore. On the positive side, a
There was pressure for ASP.NET WebForms team to offer lot of external developers took MVC out for a spin and gave
something that could compete with Ruby on Rails. The fo- detailed feedback to Microsoft through CodePlex. On the
cus on modern Web development led to the Mix conference, negative, there wasn’t any way for those same developers to
which first ran in Las Vegas in March 2006. The subtitle of directly contribute code to the MVC project.
Mix06 was “the next Web now.” It was at the Mix06 con-
ference that Microsoft announced the creation of CodePlex But building MVC through CodePlex did make MVC better, if
as a so-called “source forge” for open-source projects. One perhaps delivering it a bit slower; the first Community Tech-
of the first successful projects created on CodePlex was the nology Preview (CTP) of MVC arrived in December of 2007, with
The need to organize open source efforts at Microsoft led In February of 2014, Satya Nadella became CEO of Microsoft.
to the creation of MS OpenTech. MS OpenTech was created By April of 2014, he was keynoting at the Microsoft Build
as a wholly owned subsidiary of Microsoft focused on open- conference and announced that Windows would be free on
source development. The most visible part of its efforts was all devices that have a screen nine inches across or smaller.
making sure that important open source projects, like Redis And this is the same keynote mentioned at the beginning
and MemCacheD, for example, ran great on the Microsoft of this article where Anders Heljsberg published Roslyn to
stack. Microsoft developers moved to MS OpenTech to con- GitHub as a cross-platform, open source C# compiler-as-a-
tribute to these open-source projects. service. Version 1 of TypeScript also shipped at Build.
MS OpenTech was also a place where Microsoft developers The .NET Foundation was launched at Build 2014 as well;
worked to make existing closed-source software into open similar to the Apache Foundation, it serves as a manage-
source projects. Developers of the closed-source project ment point for .NET open source projects. At Build, numer-
would work with Microsoft patent lawyers to review all ous .NET projects were committed to the foundation, in-
the patents filed for the project. Making that project open cluding ASP.NET MVC, Web API, and Web Pages, some of the
source meant invalidating the patents, so a lot of time was original open source projects at Microsoft.
spent sorting good from bad, valuable from non-valuable.
By the fall of 2014, Microsoft announced .NET Core: a com-
An example of this transformation was Entity Framework, plete rewrite of .NET as a cross-platform, open source devel-
first released as a closed-source product with .NET Frame- opment framework. It will take 18 months for version 1.0 to
work 3.5 SP1 back in 2008. In 2012, Scott Guthrie announced
that Entity Framework Version 6.0 would be open-source,
and it released under the Apache 2.0 license in 2013. This
release came alongside the ASPNetWebStack that included
MVC, WebAPI, and Web Pages, an entirely open source set ADVERTISERS INDEX
of tools under the Apache 2.0 license with source code on
GitHub and distributed via NuGet.
Advertisers Index
Microsoft had exercised its open source muscles in a variety of
ways, starting projects from scratch, like MVC, as open source Amazon Web Services (AWS)
projects. They were distributing third-party open source librar- go.aws/codemag 76
ies like jQuery as part of a product offering and making con-
CData
tributions to existing open source projects. And perhaps most
www.cdata.com 11
remarkably, taking closed-source projects like Entity Framework
and turning them into open source libraries. It was a huge CODE Consulting
change at Microsoft, but bigger changes were coming: The www.codemag.com/consulting 65
Cloud. CODE Legacy
www.codemag.com/legacy 53
Back at the Microsoft Professional Developers Conference in
Commercial UAV Expo Americas
2008, chief architect Ray Ozzie announced Windows Azure
www.expouav.com 45
as Microsoft’s cloud offering. The first public offerings came
in February of 2010 with support for SQL Azure, PHP, Java, DevIntersection Advertising Sales:
and .NET. The cloud was new then, Amazon had gotten to www.devintersection.com 2 Tammy Ferguson
832-717-4445 ext 26
market a couple of years before, but existing Microsoft cus- dtSearch [email protected]
tomers were not in a hurry to move. At that time, Steve www.dtsearch.com 19
Ballmer said “For the cloud, we’re all in.”
JetBrains
www.jetbrains.com 29
By 2013, the struggles around Windows 8 and the shifts in
the marketplace had made it apparent that the future of LEAD Technologies
Microsoft lay in the cloud. For decades, Microsoft had fo- www.leadtools.com 5
cused solely on building products and tools that sold cop- Nevron Software, LLC
ies of Windows. Now Microsoft was making Azure its pri- www.nevron.com 7
mary focus. As part of the refocusing of Microsoft, Steve
PLURALSIGHT
Ballmer announced his retirement: Thirteen years as CEO
www.pluralsight.com 75 This listing is provided as a courtesy
was enough, and the search was on for his replacement. to our readers and advertisers.
The Tech Academy The publisher assumes no responsibi-
While that search was taking place, there were serious con- www.learncodinganywhere.com 37 lity for errors or omissions.
versations about what development tools made sense in a
with the project. We’ll look at some updated COVID-19 num- In late April and early May, New Jersey was reporting nearly
bers, show some new metrics, and some new visualizations. 1,800 deaths per week. Then that number declined a few hun-
dred each week, to a low of 268 the week of 6/20. Then the
following week of 6/27, the death count spiked to nearly 2,100
Stages of Data, Literally and Figuratively for that week, even though case counts had been dropping
I “retired” my Baker’s Dozen Productivity series that ran consistently for two months. As it turns out, in the week of
from 2004 through 2017 and built a new series brand with 6/27, health officials went back and reviewed medical data and
“Stages of Data.” One of the goals was emphasizing the determined that there were 1,800 “probable” COVID deaths go-
different phases of an analytic solution: identifying source ing back a few months, thus the weekly spike. Obviously, if the
Kevin S. Goff data, exploring extract strategies, organizing data into dif- major data sources are counting it, we need to count it: but we
kgoff@kevinsgoff. net ferent model layers, reporting on and presenting data, etc. also need to be able to explain any spikes of that magnitude.
www. KevinSGoff. net
@StagesOfData In addition, there’s also another dimension to analytic so- A similar situation occurred in New York at the end of June.
lutions: the points in time when certain analytic perspec- After weeks of declining death counts, New York experi-
Kevin S. Goff is Database
architect/developer/speaker/ tives take on a stronger meaning. For instance, you need a enced a spike of about 700 deaths that occurred over sev-
author, and has been period of time to even begin thinking about trend analysis. eral weeks and there was a delay in the reporting. This kind
writing for CODE Magazine Along with that, you need to identify blocks of time that of situation obviously skews any trend analysis. This is a fact
since 2004. He was a mem- hold significance. In the case of COVID-19 reporting, many of life, but we need to be prepared to explain it.
ber of the Microsoft MVP who are following this data have eschewed (rightly so) daily
program from 2005 through analysis. Over time, even weekly analysis can be problem- The moral of the story: Know Thy Data. The final response to
2019, when he spoke atic. Months or even years can go by before anyone finds the a wonky number should never be, “That’s what the data feed
frequently community temporal “sweet spot” in this kind of data, but I’m finding said.” If the number is bizarre, go find out why. Know Thy Data.
events in the Mid-Atlantic that taking a picture of numbers over the last two weeks and
region and also spoke comparing to the prior two weeks gives a better picture of
regularly for the VS Live/ how a particular geography is progressing/regressing dur-
Live 360 Conference brand ing this pandemic. Know Thy Data. The final response
from 2012 through 2015.
There’s also a corollary to stages of data: “Know Thy Data.”
to a wonky number should never be,
I’ve known some very talented and sharp programmers, but “That’s what the data feed said.” If the
unfortunately, a few of them didn’t recognize the value number is bizarre, go find out why.
of understanding the data. The old cliché is true: Context
matters. I recall years ago working with a Web developer
who built a new summary Web page that incorrectly showed
sales in the billions of dollars instead of low millions. There
were multiple reasons for the difference, but the bigger is- What’s on the Agenda for Today:
sue was that the developer knew the Web page was show- Here are the topics for today:
ing data in the billions and didn’t realize that it was or-
ders of magnitude off. Ideally, the developer should have • A new state profile page with ranking formulas
realized it. Unfortunately, the business side wondered, • New trend-based measures
“Don’t our developers know our business and sales num- • Defining custom filter groups
bers? Didn’t they realize this was way off?” They had a • A new visualization page to show death trends
point. • A recap of the Analytic playbook
• A look ahead to the next installment in this series
Similarly, when you work with data, regardless of the physi-
cal stage, you need to know the context of the data and be
able to spot any MAJOR outliers. I’m not saying you should
New State Profile Page with
be able to detect if sales went up 10% from month to month: Some Rankings
I’m talking about face-validity issues. Two of them came up In keeping with the theme of content reward, I wanted to
in the last two weeks regarding COVID data. build a summary page to show all the major COVID statistics
28 Stages of Data: A Playbook for Analytic Reporting Using COVID-19 Data, Part 2 codemag.com
codemag.com Title article 29
Figure 1: State Profile Page with new metrics/rankings and an overall composite ranking
for a state. I want this to be available either as a drill-down In Figure 1, you see in the upper right that Massachusetts
or even as a report tooltip. Additionally, I wanted to rank has the third highest total death count (8,310 deaths), and
the state from high to low compared with other states for the fourth highest death count per 100K residents (120.57).
each statistic, and then come up with a composite rank- Although those two ranking numbers are nearly the same
ing. This last part is a challenge: how can you rank states (third and fourth), they do illustrate that population and
according to overall impact? Obviously, you might initial- population density can factor into some of the rankings for
ly rank based on death numbers: but then again, smaller each metric. The colored map by county is based on what-
states have some very bad numbers for population density. ever metric I chose to display—in this case, deaths, with
Middlesex county in red to show the county with the highest
Figure 1 shows a Power BI report page for a state profile. number of total deaths.
I’ve chosen Massachusetts.
Now, let’s take a look at the overall ranking of 19, based on the
I ranked states with respect to each other, across all the met- six metrics with an asterisk beside the individual rankings. For
rics in Figure 1. I’m also going to show an overall composite the first three metrics, the state is doing “better” than most
rank based on six metrics that I’ll reference below. Gener- states. For the last three, the reverse. Going from left to right:
ally speaking, the lower the rank, the worse the situation for
that metric. So the state with the highest overall cumulative • 37th in the country in terms of deaths in the last two weeks
deaths (New York) will be ranked #1 for total death count, as a percent of two weeks prior (trending down 41.77%)
and the state with the lowest overall cumulative deaths (Wyo- • 44th in the country in cases in the last two weeks as
ming) will be ranked #48 for the same metric. a percent of two weeks prior (trending down 3.05%)
30 Stages of Data: A Playbook for Analytic Reporting Using COVID-19 Data, Part 2 codemag.com
• 45th in the country in terms of Case Threshold Per- This is simply one way to assess an overall impact score for
formance Index (no more than 50 new cases last two a state, relative to other states. Massachusetts is the “19th
weeks, per 100K residents) worse” in terms of overall impact. The six metrics above
• 5th in the country in terms of Deaths per Case, at 7.46% use a combination of current trends (where the state is do-
• 4th in the country in terms of Deaths Per 100K resi- ing well compared with most states) and overall numbers.
dents (120.57) The state has one of the higher death tolls in the U.S. but,
• 3rd in the country in terms of Deaths per Square Mile (1.06) as you can see from Figure 2, they have been trending
better.
If you add up all the ranking points, that sums to 138. Let’s
take a step back again. Ideally, a state (we’ll call it State A) So how did I perform the rankings? Because I’m using Power
with no cases and no deaths would be ranked #48 in each of BI for the visualizations, and ranking might be contingent
the 6 COVID metrics I’m using for a composite ranking, for on run-time filters, it’s best to use the RANK functions in
a grand total of 288 ranking points. At the other extreme, Power BI DAX to rank dynamically at runtime.
a state (State B) that was the absolute worst in all metrics
would be ranked #1 in each of the six COVID metrics, for a Let’s take a look at the third metric of the six, where we
grand total of six ranking points. don’t want more than 50 new cases per 100K residents in
the last two weeks. This metric was used in Pennsylvania
State A would be ranked #48 out of 48 overall, as 288 rank- as a guide for re-opening counties, and I’ve read that other
ing points is the maximum. That means, according to this states have followed suit (with some variations on the base
metric, that State A has been “least impacted” by COVID. threshold of 50). Remember that I stored population at the
Conversely, state B would be #1 out of 48, as six ranking county level in the table StateMasterPopulationStage, so
points is the lowest possible (again, lower is worse). There- you first need to establish the population for the state, and
fore, State B would be “most impacted.” come up with the goal/threshold:
codemag.com Stages of Data: A Playbook for Analytic Reporting Using COVID-19 Data, Part 2 31
CasesLast14DaysPer100KPopulationGoal = That score of .86 for the metric (cases over the last two
(sum(statemasterpopulationstage[population]) weeks versus a goal of no more than 50 new cases per 100K
/ 100000) * 50 residents) is one of the better ones in the country; on this
specific metric, they are ranked #45 (again, lower rankings
As Massachusetts has 6,892,503 residents, that means a goal are a reflection of negative metrics). Here is the Power BI
would be no more than 3,446 new cases in the last two weeks. DAX formulate for determining how that Index ranks across
Their case count in the last two weeks was 2,953, which all states:
means an overall index of .86. (As a general statement, an
index of 1 or lower is considered “in the right direction”). StateCaseThresholdPerformanceRank =
rankx(all
The calculation of the .86 for the Index is based on this DAX ('statemasterpopulationstage'[statename]),
formula: calculate( [CaseThresholdIndex]))
Figure 5: Weekly numbers for the top two counties in Nevada (based on deaths)
32 Stages of Data: A Playbook for Analytic Reporting Using COVID-19 Data, Part 2 codemag.com
Here is the DAX formula that determines the dynamic mea- last two weeks, you can see a huge death spike compared to
sure, based on the user selection. two weeks prior (Figure 5).
DynamicMeasure = The DAX formula for this is a bit tricky, as you need to take
switch( values ( ShowMeasure[OptionName]), into account either division by zero, or instances where the
"Show Cases", sum(CovidHistory[Cases]), numerator is zero.
"Show Deaths", sum(CovidHistory[deaths]) ,
etc.) WeeklyDeathIncrease = if(
sum(covidweeklycounts[DthsL2Wks]) > 0 &&
From Figure 4, you can see that Nevada has the highest sum(covidweeklycounts[Dths2WPriL2Wks]) <= 0,
death rate increase. When you look at the counties on the 1,
right side of the dashboard page and sort on deaths in the if( sum(covidweeklycounts[DthsL2Wks]) <= 0 &&
Figure 6: A significant spike in weekly numbers for the top counties in South Carolina
codemag.com Stages of Data: A Playbook for Analytic Reporting Using COVID-19 Data, Part 2 33
Figure 8: Filtering based on the top five states (based on cases in the last two weeks)
In this situation, Nevada is at the lower end of the coun- Figure 7 shows the overall summary page for the nine coun-
try in state population, although that doesn’t diminish the ties in the NYC/Northern NJ area that represent the huge
significance of the increase. You could certainly adjust that hotspot of deaths.
metric from “deaths in the last two weeks” to “deaths per
capita in the last two weeks”. Figure 8 is the overall summary page for the top five states.
Before we move on, one other note: Back in Figure 4, you Okay, so how did I create these custom groupings? First,
saw Florida and Texas near the top of the list, consistent you create a new table called CustomGeography. You can
with the news stories in the last few weeks about the huge populate it with county FIPS code values.
spikes in those states. There’s another state that currently
has very concerning numbers: South Carolina. In Figure 6, select * from CustomGeography
I’ve selected South Carolina to view the top counties. where AttributeName =
'NYC and North Jersey hotspot'
South Carolina currently ranks #9 in my overall composite and AttributeValue =
ranking, driven mainly by their alarming rise in case and 'NYC and North Jersey'
34 Stages of Data: A Playbook for Analytic Reporting Using COVID-19 Data, Part 2 codemag.com
In the case of the nine counties in the NYC/NJ area, I popu- A New Visualization to Show States
lated them manually, as shown in Figure 9.
with Growing Death Rates
Of course, I might also want to filter on “all others, so I You can take your metric for deaths the last two weeks as
need to pull all the FIPS Code values for the ones that don’t a percentage of deaths the prior two weeks and show it in
meet that criteria, and insert them into the CustomGeogra- a visual. In Figure 10, I’m showing the states colored by
phy table with an Attribute Value of “Not NYC and Northern the death trend for the last two weeks: States in red have
Jersey.” the highest trends, light yellow and light green have either
slightly above or below zero trends respectively, and green
states have trends well below zero.
After about the umpteenth time Here’s one thing you can see with the scatter chart in Fig-
of selecting nine counties or five ure 10: New York and New Jersey are wide apart from the 0
X-Axis line. As I said in the beginning of this article, New
states again and again and again, York had a delayed death count dump in the last two weeks,
I decided to build some groupings. resulting in a very high increase. New Jersey had a delayed
death count dump three weeks ago, meaning the trend is
artificially low for the current two weeks.
select fipscode from statemasterpopulationstage You might want to exclude them for the purposes of analyz-
where fipscode not in (select fipscode from CustomGeography ing the other states. Power BI runtime allows you to right-
where AttributeName = click on a plotted point (as I’ve done in Figure 10) and ex-
'NYC and North Jersey hotspot' clude the states, one at a time.
and AttributeValue =
'NYC and North Jersey' In Figure 11, you can see an updated scatter chart that
and FIPSCode is not null) shows the overall death count on the Y axis and the death
trend for the last two weeks on the X axis. Now that New
This first group filter definition is a “static” set of values. If you York and Jersey are excluded, the scatter chart rescales. Two-Week Trends or
want to set a predefined lookup group/filter based on the top Four-Week Trends?
five cases, you can define one called “Top Five States,” and pop- California, Florida, and Texas are three states with the high-
ulate the county codes for those five states with a SQL query: est death counts that also have a high death trend over the The composite ranking
last two weeks. (You can also see South Carolina and Nevada concept in this article is a
select fipscode from statemasterpopulationstage all the way out to the far right on the Death Trend Y axis, discussion-starter. Someone
join ( although their populations are lower). suggested I use a four-week
select top 5 stm.statename,
trend instead of a two-week
trend, because even two
sum(cases) as TotCases You can click on one of the states (either a plotted point in
weeks doesn’t take into
from covid19DailyCounts cdc the scatter chart or the state in the map) to see the coun-
account a full virology cycle
join statemasterpopulationstage stm ty breakdown at the bottom of the page. I’ll click Florida,
of incubation and delays in
on cdc.fipscode = stm.FIPSCode which gives me the county breakdown in Figure 12. Here reporting data. It wouldn’t be
where casedate between you can see that Miami Dade County’s deaths have gone up the proverbial rocket science
dateadd(d,-14, 48% in the last two weeks, and Broward county’s deaths to either change this to use
(select max(casedate) from datelist) ) have nearly doubled (an increase of 192%) a four-week cycle, or even
and (select max(casedate) from datelist) provide the option to toggle
group by stm.statename between the two of them.
order by TotCases desc ) t The Playbook, Revisited I’ve already shown how you
on statemasterpopulationstage.statename = In Part 1 of this article series, I talked about common can implement dynamic
t.statename themes in analytic applications, such as shared filters, con- measures in Power BI.
Figure 10: Scatter chart and filled map of states based on two-week Death Trends
codemag.com Stages of Data: A Playbook for Analytic Reporting Using COVID-19 Data, Part 2 35
Figure 11: Same as Figure 10, but without New York/New Jersey (notice scatter chart rescales)
Figure 12: The same metric but for the counties in Florida
Sanity Check and tent reward, dynamic measures, trend-based metrics that In the Next Regular CODE Article
Regression Testing truly reflect changes in reality, and combining metrics to- When I set out to write on this topic, I wasn’t sure if I’d
gether to form a picture. I also talked about validation: in stretch it out over one or two issues. Well, I can say for a
I’ve had several nicknames
this case, whether it’s looking at any huge changes in num- certainty that there will be a third, and here are the topics:
in my career, some funny
bers, or verifying against other news sources. You can do
and some I can’t repeat. One
of my co-workers calls me
some of that with automated scripts/procedures, but some • A complete walkthrough of the ETL steps. I had
“Data,” after the Brent Spiner requires good old-fashioned eyeballing and reading. planned to cover the ETL, but the truth is that I wound
character in the Star Trek up changing my underlying data model in the last
Generations series. I look at There are also pages from the playbook that fall under the month, to more effectively handle some of the trend-
data as often now as I studied “process” area. I’ve been developing this project on my own ing. So my ugly little secret right now is that although
baseball stats as a kid. When I time, outside of my normal work schedule. (Does anyone in IT the dashboard application reflects the data, some of
see a number that looks odd, actually have a normal work schedule?) I’ve had some GoTo- the underlying ETL is nothing I’d want to present. I’ll
I track down why. Yes, I’ve Meeting sessions with some friends and colleagues, and either be cleaning that up and that will be the primary focus
built automated tools that I’ll demo what I’ve done, or I’ll give them the link and let them of the next article.
look for significant changes navigate while I watch. Just a 15-minute session can raise • I’m in the process of moving my back-end data-
to data and they’ve saved me ideas or opportunities for improvement. To be sure, this can base to Azure and will talk about some of the steps
time. Still, there’s no substitute backfire if you do it too often, but that regular feedback loop involved.
for walking back through can be very helpful in maintaining continuous improvement.
the analytic paths of your Stay Safe and Play It Smart
application to make sure that As a big fan of the musical rock group “Rush,” I’m reminded
either you haven’t broken Final Thoughts: of some lyrics from a 1991 track called “Neurotica” that goes
anything with a change and/ My primary website (www.stagesofdata.net) has an entire like this: “Fortune is random, fate shoots from the hip, I
or that some data anomaly section devoted to this COVID-19 reporting project. This is know you get crazy, try not to lose your grip.” We need to be
now exists for which you
my documentation center for the project. mindful of our actions every day. We need to absolutely re-
haven’t identified a pattern.
spect this virus, because this virus has absolutely no respect
There needs to be a healthy
mix of automated tests and
The public URL for the dashboard is https://bit.ly/2A6lk3a. whatsoever for us. This isn’t just a virus that causes pneu-
good old-fashioned eye- The link is also available on my primary website. I update monia (which itself has led to pandemics): even healthy
balling. the site weekly on Sunday evenings, after pulling down the people have suffered severe vascular damage. Still, we need
data from Saturday and viewing the contents. I also post to keep our grip on this cold reality. The vast majority of
notes on any new weekly findings. people in the world know this, but still, EVERYONE needs be
safe and play it smart, at all times.
Finally, my primary website also contains some links to
videos I’ve posted on YouTube that cover some of the main Kevin S. Goff
features of this dashboard.
36 Stages of Data: A Playbook for Analytic Reporting Using COVID-19 Data, Part 2 codemag.com
ADVERTORIAL
Learn Coding Anywhere The Tech Industry is Still Hiring What Sets the Tech Academy Apart
The Tech Academy programs require no technical Despite recent global events, we are placing a high There are other online schools, so what makes
background or coding experience. Our classes are number of graduates in remote, technical positions. The Tech Academy special?
deisgned for absolute beginners. We specialize in While many companies have been struggling,
coding boot camps that train students in a wide the tech industry has been impacted less than • No tech background or coding experience
range of technology subjects, including: others. is required
• Online and in-person training
• Website development During these uncertain times, one thing is for sure: • Open enrollment—start anytime
• Computer programming the need for technology isn’t going anywhere – • Flexible scheduling options
• Design in fact, it’s increasing. • Self-paced program
• Data science • Outstanding job placement assistance
• And more... Prepare for your future today by completing a • Multiple financing options
Tech Academy Boot Camp from the comfort an
These programs can be sompleted in as little safety of your own home.
8 weeks and prepare graduates for working in
the tech industry.
Contact us at:
[email protected]
Or call: (503) 206-6915
37
codemag.com
FIND OUT MORE AT LEARNCODINGANYWHERE.COM Title article
ONLINE QUICK ID 2009061
and Vue. On May 19, 2020, Blazor WebAssembly was finally articles that outline exactly that (“Re-Assembling the Web
released, and full-stack Web development with .NET received with Web Assembly and Blazor” by Rick Strahl, issue Septem-
a spot on the track. ber/October 2018, https://codemag.com/Article/1809061/
Re-Assembling-the-Web-with-Web-Assembly-and-Blazor;
Microsoft introduced server-side Blazor back in September and “A New Era of Productivity with Blazor” by Ed Charbon-
2019, which allowed the community to delve into Web de- neau, CODE Focus Issue November 2019, https://codemag.
velopment using C# and .NET. Server-side Blazor executes com/Article/1911052/A-New-Era-of-Productivity-with-
all logic on the server and communicates with the browser Blazor). Although some of the code snippets/syntax and
through a constant SignalR connection. The programming namespaces might have changed with the newer releases
Otto Dobretsberger, syntax and the project structure is identical to client-side of .NET Core, the fundamental ideas and architectural de-
PhD Blazor projects, but we can still point out significant differ- signs around Blazor have remained the same. Therefore, I
[email protected] ences, as well as pros and cons between the two approaches. still consider these articles a valid resource for information.
What I want to highlight in this article is something I’m still
Otto is a Senior Software not able to find a lot of information or examples on: Real
Developer with EPS Software. The Qualifying: Client-side world applications that go beyond the tutorials and typical
He earned a Bachelors
Degree in Biomedical
vs. Server-side Blazor starter apps people develop to play around with and write
Until the release of WebAssembly, in-browser logic had to be about. In light of the current global situation revolving
Informatics in Austria, and a
executed almost exclusively as JavaScript. Regardless of the around the COVID-19 pandemic, I figured that I can write an
Masters and PhD in Computer
Science from the University setup of your back-end, a Web application without front-end application that enables the tracking of COVID-19 statistics,
of Houston. His background JavaScript was unthinkable. Client-side Blazor challenges and that allows me to compare different countries side by
is in heavy computational JavaScript’s dominance in the browser and adds C# to the side, including graphs. I’ll show how to set up the project
genetic and genomic data pool of choices. Because it’s pre-compiled into WebAssem- and make service calls to REST APIs for data acquisition. I’ll
analysis using C and C++. bly before being downloaded into the browser, it’s destined also demonstrate that a client-side Blazor application can
He specializes in WPF, C#, to be significantly faster than the JavaScript counterpart, easily be converted into a server-side Blazor application.
and C++, and is proficient in especially for applications relying heavily on computations Both the client-side and server-side version of the Blazor
several other languages as and performance. Even though it might still be early to sample project are already published on Microsoft Azure and
well. His experience ranges talk about using client-side Blazor for online gaming in the publicly available (links at the end of the article and in a
from working on projects browser, it certainly brings that finish line a little closer (a sidebar).
in the fields of biomedical line that JavaScript has yet to fully cross).
image processing, genetic
and genomic data analysis, In contrast to server-side Blazor, client-side Blazor has the The Race to a Real-World Example
analytical software for the capability to also work offline, as it doesn’t require a con- Start off by creating a new Blazor project in Visual Studio
oil/gas industry, and custom stant connection to the back-end. However, this aspect in 2019 (Note: VS2017 doesn’t support client-side Blazor proj-
control development. particular is a double-edged sword, as the download size ects). It’s imperative to ensure that you also have the most
of a single client-side Blazor component is most likely far current version of .NET Core SDK (3.1.301, as of time of writ-
Since 2014, Otto is also an
Adjunct Professor at the greater than a comparable solution developed in JavaScript ing) installed. You will be prompted to choose between a
University of Houston, or server-side Blazor. In order to run Blazor client-side, you Blazor Server App and a Blazor WebAssembly App--I chose the
having taught various have to download the entire runtime for the Web applica- latter (Figure 1).
programming courses from tion, which your compiled Web project will then execute on.
C++ to Java. That means that even an empty site, or the typical “Hello Visual Studio sets up the project for you and gives a start-
World” project, will already amass to several megabytes ing point, which should be quite familiar to everyone who’s
When he’s not writing in download size. Additionally, this also has an impact on experimented with Blazor before, be it client-side or server-
code, he’s usually found non-standard browsers. Although most browsers are per- side. You can see three default Razor components in the
somewhere in a gym, fectly capable of dealing with WebAssembly, some niche or Pages folder: Index, Counter, and FetchData. If you compile
training for his next embedded browsers might not be and thus won’t be able and run the application, your browser shows the familiar
powerlifting competition. to load a website built on client-side Blazor technology. In sample application that Microsoft put together, which is the
that case, server-side Blazor is still an option, as the cli- same for client-side and server-side Blazor projects. This
ent only receives standard HTML and JavaScript from the very example is already in one of our previous Blazor ar-
server. ticles, so I won’t repeat that discussion.
I’m not going to spend much more time on the characteris- Today, I have one goal: A page displaying COVID-19 data and
tics of a Blazor application, the set-up, its ecosystem, or its graphs, with direct country comparison capabilities. Start
architecture, as CODE Magazine has already published two by creating a new component in the Pages folder, and name
Before you get started, you also need to answer two impor-
tant questions:
For the proposed layout, choose a simple horizontal layout BigInteger casesPer100k = BigInteger.Divide(casesDividend,
of columns, each of which represents one country. Accom- new BigInteger(Convert.ToInt32(countryToAdd.Population)));
plish that with a css class selector that you apply to a <div>:
timestepdeathper100k.Cases =
Convert.ToInt32(casesPer100k.ToString());
.arrange-horizontally > * {
display: inline-block; timeStepCollectionDeathPer100k.Add(timestepdeathper100k);
text-align: center; }
Listing 5: Displaying the country information and graphs as columns within the component
<div class="arrange-horizontally"> <DxChartCommonSeries AggregationMethod="@(i =>
@foreach (var country in CountryDatasets) (int)i.Average())"
{ NameField="@((CovidTimeStep c) => "")"
<div style="width: 350px"> ArgumentField="@(i => i.Date.ToString("MM/dd"))"
<span>@country.Name </span> ValueField="@((CovidTimeStep i) => i.Cases)">
<button @onclick="@(() => RemoveColumn(country.Name))" <SeriesTemplate Context="settings">
style="width: 60px; height: 20px; color: red; <DxChartLineSeries Settings="@settings"
font-size: x-small">Remove</button> Color="@(getColorForCountry("confirmed"))">
<br /> </DxChartLineSeries>
</SeriesTemplate>
<span><b>Population:</b> @country.Population </span> </DxChartCommonSeries>
<br /> </DxChart>
</div>
<span><b>Total Cases: </b> @*...same approach for death cases & norm. death cases*@
@country.ConfirmedCases</span> </div>
<br /> }
<div> </div>
<DxChart Data="@country.ConfirmedTimeSteps">
Figure 5: Select the App Service you created in MS Azure to deploy your client-side Blazor application.
component, which shows a graph that allows you to com- mean that it should or needs to be used for every single
SPONSORED SIDEBAR: pare individual countries as a separate series within one upcoming Web project. And for some projects, server-side
Interested in Moving chart. In this visualization, you can even compare coun- Blazor might even be better suited. Ultimately though, I can
to the Cloud? tries to US states (here is where that Province parameter confirm the following:
CODE Can Help! previously mentioned comes in handy). I included a date
picker to select From and To dates, a color picker for chart Full stack .NET Web development has shifted into second
Take advantage of a line colors, and the ability to display the daily case chang- gear and moved over into the passing lane. JavaScript-pow-
FREE hour-long CODE es as opposed to the accumulated total number of cases. ered frameworks might still lead in this race, but Blazor is
Consulting session I also changed the application color scheme a little bit definitely equipped with a Turbocharger and, at some point,
(yes, FREE!) to jump-start (Figure 7). might challenge JavaScript for the Pole Position in this
your organization’s plans Grand Prix of Web Development.
to develop solutions on
the Microsoft Azure or Post-Race Conference and Analysis Otto Dobretsberger
Amazon Web Services (AWS) Both the client-side and server-side Blazor version of this
cloud platforms. application remain under development and will receive con-
For more information, tinuous updates on a regular basis as more features and
visit www.codemag.com/ components are added. This project has led me to the con-
consulting or email us at
clusion that the client-side Blazor technology is certainly
[email protected].
ready for real production projects. That, of course, doesn’t
Louis Grasse
A re-imagined
virtual event where expouav.com
the commercial drone
community will gather
Visit the
to learn, connect virtual
and drive the exhibits
industry forward. for free!
But here we’re going to formally introduce it and explain One of the biggest challenges is to know whether a given
how to get started with it. We’ll also explain how you can experience is viable and fun to use and also that it solves a
tweak it by using scripting at runtime. given problem. Usually designers use mockup tools to cre-
ate an impression of a UX experience, and then try to judge
whether these mockups should come to life. Historically,
tools like Visual Basic or HyperCard were used to this pur-
If a picture is worth a thousand pose. Framer is a more modern version of such a tool for 2D.
words, a prototype is worth a Development of Maquette started in early 2017 after real-
Stefan Landvogt
thousand meetings. izing that no such simple tool is available for the VR and
[email protected]
Tom & David Kelleyç AR context. A small team at Microsoft started the inception
Stefan is a Principal Software of the tool, and the first goal was to have a feature set
Developer for Microsoft rich enough so that the development of Maquette could be
and helps to ship Maquette driven by using Maquette itself. A very rudimentary version
to its customers. The target users for Maquette are mainly designers or de- was available after around three months of work, and since
velopers, people who’re looking for a fast way to evaluate then, the development of the tool has been done by using
He holds a Masters equivalent their ideas in AR and VR without actually building them. Maquette itself (kind of like a C-compiler written in C).
degree from the University Usually a designer creates a mockup in a 2D tool like Pho-
of Würzburg in Applied
toshop and other UX design tools and then presents it with
Computer Science and
PowerPoint on a traditional 2D screen. With VR and AR and
Artificial Intelligence and
started his career working
the addition of the third dimension, these mockups have Development of Maquette started
the potential to deceive the customer in the viability of a
on expert systems.
product. After getting funding, the designer teams up with
in early 2017 after realizing
a developer, who has to make a serious investment in time that a simple tool was available
and programming to create the experience—often in tools for VR and AR.
like Unity or Unreal. After the developer invests significant
time to implement the design, there are often realizations
that the design is faulty now that it’s been translated into
the VR/AR environment. The development process itself is also different from most
products: It happens in a so-called cabal setting with no
Maquette allows creation of a spatial prototype in a context management structure and no formal roadmap of the final
that can be presented in the medium that the experiences product. The team decides which feature will have the big-
Vassili Kaplan are built for. With it, it’s possible to iterate early on a UX gest impact—design- or business-wise—and implements
[email protected] and learn whether the application is actually useful and fun that, ships it to the customer, listens to feedback, and re-
http://www.iLanguage.ch to use. The intention of Maquette is to help AR and VR devel- peats. This all happens while designers, programmers, and
opers conceive and refine their concepts and help find the technical artists sit in the same room or are constantly con-
Vassili is a former Microsoft
next AR and VR killer application faster without the need to nected through chat applications. This leads to a product
Lync developer who has
worked in several countries.
fully implement it first. that might not have some “basic” features—like a layout
He has a Masters in system or easy alignment at first—but only has features that
are actually used and needed. With that, the team added, re-
Applied Mathematics with
Specialization in Computa-
Introduction to Microsoft Maquette fined, and fully realized features as it learned from feedback
tional Sciences from Purdue The biggest challenge with AR and VR applications is the and as the customers requested. After around nine months,
University, West Lafayette, addition of the third dimension to their experience. Also, the decision was made to share the internal tool with the
Indiana and a Bachelor the user interface is usually co-located with the actual general public, so Microsoft Maquette shipped through the
in Applied Mathematics experience—which leads to lots of interesting interaction Microsoft Store and Steam in October 2018, and through the
from ITAM, Mexico City. problems. Oculus Store in July 2020.
Even though there have been VR and AR headsets available The work to introduce scripting and interactivity was han-
in academics since Douglas Engelbart built the first proto- dled in a similar fashion. The goal has been to make easy
types in the 1960s, they only became available recently to problems in Maquette easy to solve, such that the “Hello
the masses after the availability of high-resolution displays World” for interactivity won’t require weeks of investment
from mobile phones, new inventions in tracking technology, and learning. How to best expose approachable, AR/VR-
and access to the power of high-end graphics cards. friendly interactivity and scripting isn’t a solved problem
function PutInFrontOfUser(obj, x, y, r, g, b)
{ play around with this) and the colors RGB (red, green, blue)
obj.Position = user.PositionInFront(0.6); parameters. The scale parameter is always set to 0.1 for all
obj.rotation = user.RotationToFace(obj); coordinates. You can easily play around with different param-
obj.scale = V3(0.1, 0.1, 0.1); eters, z-coordinates, scales, transformations, etc.
obj.color = Color(r, g, b);
obj.translate(V3(x, y, 0.0)); The CreateCubeFromMenu() function creates a red cube (be-
return obj; cause (r, g, b) parameters of (1, 0, 0) correspond to the red
} color).
The parameters passed to this method, besides the object Creating Multiple Objects
obj, are x and y object coordinates (you can see inside of this Let’s see an example of producing a series of figures. Here is
method that the z coordinate is always zero, but feel free to the CSCS code to create n cubes:
As you can see there, each cube has a slightly different color
than its predecessor. This is accomplished via applying the
delta parameter to the RGB color parameters that we dis-
cussed above. The color changes from light green to red by
playing around with the RGBs. This is done by multiplying
delta by i in the call to PutInFrontOfUser() method, where i
is between 0 and n.
Figure 4: Execution of CreateCube.mqs script and adding a global action. capsuleObj = new Capsule();
circleObj = new Circle();
coneObj = new Cone();
cubeObj = new Cube();
cylinderObj = new Cylinder();
planeObj = new Plane();
sphereObj = new Sphere();
torusObj = new Torus();
tubeObj = new Tube();
Basically, you can use this extension for the following types
Figure 5: Creating 10 cubes using scripting. of debugging:
the free CSCS Extension from through the scripting help command. Visual Studio Code:
https://code.visualstudio.com/
the Marketplace, and you can The Log objects helps printing various info or debug messages. download
start modifying your Maquette Some of its methods are: log.Debug(), log.Info(), and log.Error().
JavaScript Interpreter for .Net
project on-the-fly by selecting There’s also the User object, which has methods related to JintScript:
the code and pressing Ctrl–8. the position of the user inside Maquette. Some of the meth- https://github.com/
ods on that object are: user.PositionInFront(), user.Rota- sebastienros/jint
tionToFace(), user.Scale(), user.Position(), user.Rotation(),
user.Forward(), and a few others. ECMAScript Language
Figure 6 shows a sample session when the user typed the Specification:
http://www.ecma-international.
help command. Note that in order to call the next (or previ- The Viewpoint object is responsible for Maquette Viewpoints.
org/ecma-262/5.1/
ous) command from the command history, you type Ctrl-K Some of the useful methods and properties on that object
(Ctrl-I) on Windows and -K ( -I) on a Mac. This is be- are: viewpoint.GotoNext(), viewpoint.GotoLast(), viewpoint. CSCS Language E-book:
cause just pressing up and down arrows moves the cursor Add(), viewpoint.Remove(), viewpoint.Count, and others. https://www.syncfusion.com/
inside the editing area. ebooks/implementing-a-custom-
The System object is responsible for some auxiliary func- language
Note that the first two options of using CSCS Visual Studio tionality that might be useful to the user, for example:
Code Extension were previously discussed in the March/April system.OpenExplorer(), system.OpenURL(), system.GetRan-
2019 issue of CODE Magazine. domInInterval(), and some others.
scenes.Current = sceneCounter;
Wrapping Up
Microsoft Maquette is a tool designed to facilitate spatial pro-
totyping and address a few existing problems in AR and VR
today. One of the first steps to getting started with Maquette
is watching video tutorials at https://www.maquette.ms/
tutorials. They contain a few examples on how to get started
and move into some more advanced topics.
Spotlights Example Special thanks to Dan Newell, Jia Wang, Dan Corrigan, Ricar-
Microsoft Maquette ships with over 20 spotlights that pres- do Acosta, and Tong Chen for proofreading and suggestions.
ent you with what can be done with the tool. All of these
spotlights contain multiple scenes and every scene can have Stefan Landvogt and Vassili Kaplan
one or multiple viewpoints. A viewpoint is a place that can
be visited through a menu and can be a vantage point into
the 3D world created.
Are you being held back by a legacy application that needs to be modernized? We can help.
We specialize in converting legacy applications to modern technologies. Whether your application
is currently written in Visual Basic, FoxPro, Access, ASP Classic, .NET 1.0, PHP, Delphi…
or something else, we can help.
codemag.com/legacy
832-717-4445 ext. 9 • [email protected]
particular locale and culture. In other words, an application 9. Specify authentication as “No Authentication.” You
takes advantage of globalization to be able to cater to dif- won’t be using authentication here either.
ferent languages based on user choice. Localization is ad- 10. Click Create to complete the process.
opted by the application to adapt the content of a website
to various regions or cultures. A new ASP.NET Core project will be created in Visual Studio
2019. You’ll use the project you’ve just created later.
Broadly, the three steps you should follow to localize your
application include:
Configuring Startup
Joydip Kanjilal 1. Sift through your application to identify the localizable It should be noted that localization in ASP.NET Core is an
[email protected] content. opt-in feature and is not enabled by default. The ASP.NET
2. Create localized resources for the languages and cul- Core framework provides a middleware that is meant for
Joydip Kanjilal is an MVP tures the application has support for. localization. You can add this middleware to the request
(2007-2012), software 3. Implement a strategy that can be used to select a lan- processing pipeline by calling the UseRequestLocalization
architect, author, and guage or a culture per request. method on the IApplicationBuilder instance.
speaker with more than
20 years of experience.
I’ll discuss each of these points in this article as I show you First off, you should add localization services to the appli-
He has more than 16 years
how you can build multilingual applications in ASP.NET Core. cation. To add localization services to your application, you
of experience in Microsoft
.NET and its related can use the following code.
technologies. Joydip has You should have Visual Studio 2019 (an earlier version will
authored eight books, also work but Visual Studio 2019 is preferred) installed public void ConfigureServices(IServiceCollection services)
more than 500 articles, on your system. You can download a copy of it from here: {
and has reviewed more https://visualstudio.microsoft.com/downloads/ services.AddControllersWithViews();
than a dozen books. services.AddLocalization(opt =>
{
Getting Started opt.ResourcesPath = "Resources";
First off, let’s create a new ASP.NET Core MVC project in Vi- });
sual Studio. There are several ways to create a project in Vi- }
sual Studio 2019. When you launch Visual Studio, you’ll see
the start window and you can choose “Create a new project” The preceding code snippet illustrates how the localization ser-
from there. Alternatively, you can choose “Continue without vices are added to the service container. Note how the Resources-
code” to launch the main screen of the Visual Studio 2019 Path property has been used to set the path to the folder where
IDE. I’ll choose the first option in this example. resource files (for various locales) will reside. If you don’t specify
any value for this property, the application will expect the re-
To create a new ASP.NET Core 3.0 MVC project in Visual Stu- source files to be available in the application’s root directory.
dio 2019, follow the steps outlined below.
There are three methods used to configure localization in
1. Start Visual Studio 2019 IDE. ASP.NET Core. These include the following:
2. Click on the “Create new project” option.
3. In the next screen, select “ASP.Net Core Web Applica- • AddDataAnnotationsLocalization: This method is used
tion” from the list of the templates displayed. to provide support for DataAnnotations validation mes-
4. Click Next. sages.
5. Specify the name and location of your project in the • AddLocalization: This method is used to add localiza-
“Configure your new project” screen. tion services to the services container.
6. In the “Create a New ASP.NET Core Web Application” • AddViewLocalization: This method is used to provide
screen, select .NET Core as the runtime and ASP.NET support for localized views.
Core 3.0 (or later) from the drop-down list at the
top. I’ll discuss more on each of these soon.
7. Select “Web Application (Model-View-Controller)” as
the project template to create a new ASP.NET Core MVC Define the Allowed Cultures
application. In .NET, you can take advantage of the CultureInfo class for
8. Uncheck “Enable Docker Support” and “Configure for storing culture-specific information. You should now specify
HTTPS.” You won’t be using either of these here. the languages and cultures that you would like your applica-
Next, add the request localization middleware in the Config- You should also use the UseRequestLocalization extension
ureServices method of the Startup class. method in the Configure method of the Startup class to set
the culture information automatically based on the informa-
services.Configure tion provided by the Web browser. The following code snip-
<RequestLocalizationOptions> pet illustrates how this can be achieved.
(options =>
{ var options = app.ApplicationServices.GetService<IOptions<Request
List<CultureInfo> supportedCultures = new LocalizationOptions>>();
List<CultureInfo> app.UseRequestLocalization(options.Value);
{
new CultureInfo("en-US"), The complete source code of the Configure method is given
new CultureInfo("de-DE"), in Listing 2.
new CultureInfo("fr-FR"),
new CultureInfo("en-GB")
}; Listing 1: Add the request localization moiddleware in the ConfigureServices method
options.DefaultRequestCulture = new
public void ConfigureServices(IServiceCollection services)
RequestCulture("en-GB"); {
options.SupportedCultures = services.AddControllersWithViews();
supportedCultures;
options.SupportedUICultures = services.AddLocalization(opt =>
{
supportedCultures;
opt.ResourcesPath = "Resources";
}); });
options.AddInitialRequestCultureProvider
(new CustomRequestCultureProvider
Listing 3: The Custom Request Culture Provider (async context =>
public class MyCustomRequestCultureProvider : {
RequestCultureProvider //Write your code here
{ return new ProviderCultureResult("en");
public override async Task<ProviderCultureResult>
}));
DetermineProviderCultureResult
(HttpContext httpContext) });
{
await Task.Yield();
return new ProviderCultureResult("en-US"); Create a Custom Request
}
}
Culture Provider
Note that the culture providers AcceptHeadersRequest-
CultureProvider, QueryStringRequestCultureProvider, and
CookieRequestCultureProvider are configured by automati-
Listing 4: Add the Custom Culture Provider to the RequestCultureProviders list cally by default. You can also create your own custom cul-
services.Configure<RequestLocalizationOptions>(options => ture provider.
{
List<CultureInfo> supportedCultures = new List<CultureInfo>
{
Before you add your custom culture provider, you may want
new CultureInfo("en-US"), to clear the list of all the culture providers. Your custom
new CultureInfo("de-DE"), culture provider is just like any other class that inherits the
new CultureInfo("fr"), RequestCultureProvider class and implements the Deter-
new CultureInfo("en-GB") mineProviderCultureResult method. You can write your own
};
implementation, i.e., resolve the culture for a request in-
options.DefaultRequestCulture = new RequestCulture side the DetermineProviderCultureResult method as shown
(culture: "de-DE", uiCulture: "de-DE"); in Listing 3.
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders.Clear(); Listing 4 illustrates how you can clear all default culture
options.RequestCultureProviders.Add(new providers and add the custom culture provider to the Re-
MyCustomRequestCultureProvider()); questCultureProviders list.
});
Here’s how it works. It searches for a resource file matching Listing 5 illustrates how you can access localized string in
the current culture. If it finds one and there’s a matching your controller.
row with the Name as “Hello World!”, it returns the Value. It
then searches for the parent culture and if a value is found, When you run the application, the message “Hello World” will be
it returns that. As a fallback, the string “Hello World!” is re- displayed in the Web browser, as shown in Figure 1.
turned if there’s no match. Culture fallback is a behavior in
which if the requested culture is not found, the application Now specify the culture you’d like the application to use in the
selects the parent of that culture. URL as shown here: http://localhost:1307/?culture=de-DE
Figure 1: The text “Hello World” displayed using a default locale in the Web browser
Figure 2: The text message “Hello World” is displayed using the German locale in the Web browser
message as appropriate. Note how the RangeAttribute has RequestCultureProviders. SPONSORED SIDEBAR:
been used to specify the minimum and maximum number of Insert(0, requestProvider);
books authored by an author. Get .NET Core Help
Listing 6 shows the complete source code of the Configure for Free
Next, you create a resource file. Let’s create one for the Ger- method for your reference.
man locale and name it Models.AuthorViewModel.de-DE. Looking to create a new
resx with the content shown in Figure 3. project in .NET Core or ASP.
Summary NET Core? Get started with
a FREE hour-long CODE
For DataAnnotationsLocalization to work, call the AddData- ASP.NET Core and ASP.NET Core MVC provide excellent sup-
Consulting session to make
AnnotationsLocalization() method. If you’re using ASP.NET port for internationalization. Implementing it in your appli- sure you begin on the right
Core or ASP.NET Core MVC 2.0 or 2.2, here’s what you need to cations isn’t difficult either. You can take advantage of the foot. CODE consultants have
specify in the ConfigureServices method of your Startup class. built-in support for globalization in ASP.NET Core and ASP. been working with the .NET
NET Core MVC to build applications that can cater to vari- Core and ASP.NET Core teams
services.AddMvc(). ous locales. ASP.NET Core provides support for globalization since the early pre-release
AddDataAnnotationsLocalization(); through the Microsoft.Extensions.Localization assembly. builds. Leverage our team’s
services.AddLocalization(o => experience and proven track
{ Joydip Kanjilal record to make sure your
o.ResourcesPath = "Resources"; next project is a success.
}); No strings. No commitment.
For more information, visit
Here’s what to specify in the ConfigureServices method if www.codemag.com/
you’re using ASP.NET Core or ASP.NET Core MVC version 3.0 consulting or email us
or upward. at [email protected].
services.AddLocalization(opt =>
{
opt.ResourcesPath = "Resources";
});
services.AddControllersWithViews()
.AddDataAnnotationsLocalization();
In this feature, we eavesdrop on a conversation between Dr. Neil Roodyn and Markus Egger, both seasoned Regional Directors.
Talk to Dr. Neil about: Talk to Markus about:
Software development, cloud computing, machine learning and AI, ASP.NET, HTML apps
More Personal Computing, cognitive services, (including Angular, Vue.js, etc.), the cloud,
bots, conversation as a platform, true social Azure, Microservices, Windows applications,
computing, robotics, quantum computing, software strategy, and much more.
the economic singularity, and the future. You can contact him at [email protected]
Dr. Neil Roodyn has long had a passion for software development, going Markus Egger is not just an RD, but as the founder and publisher of CODE
back to the 70s when he taught himself BASIC and 6502 Assembler. In the Magazine, he’s also directly associated with this publication. In his main
90s, Neil worked on a number of different real-time systems that led to a job, he is the President and Chief Software Architect of EPS Software Corp.
thesis entitled “Software Architectures for Distributed Real-Time Systems.” (a company better known for its CODE brands such as CODE Consulting,
Neil was awarded a PhD for this thesis from University College London and CODE Training, CODE Staffing, and CODE Magazine). He is also the founder
the brand of Dr. Neil was born. Since 1995, Dr. Neil has been involved in the of other business ventures, such as Tower 48, Wikinome, and others. In his
formation of many software companies, his roles varying from mentoring own words, he spends his time “like most software developers, writing
through to directorship. Dr. Neil keeps a very active involvement in the production code” both for consulting and custom app-dev customers,
software being produced and delivered today, and provides feedback and also for his own companies. He has worked for some of the largest
to both large and small companies on how to increase the value of their companies, including many Fortune 500 companies, such as Microsoft.
software business. Markus often takes on the role as a “CTO for hire.”
Just before this crisis emerged, we did a small One interesting observation that I’ve made is that The other tool that I use very heavily in Teams—
internal conference where we brought everyone some people who were very reticent or introvert- even though it’s technically outside of Teams—is
out to Hawaii, for instance. We do it at different ed, who didn’t want to go and talk to people be- Whiteboard. When you’re working with a team
locations at least once a year. I have no idea how fore in the physical world and are now much more and you want all the people to engage, White-
that’s going to continue in the future because we vocal in the virtual world because everybody is board works really well. I love using a pen. I’m
found that super valuable. Like you discover that virtual. Now they can get in a chat room and they a stylus kind of person and I’ve always been into
your coworker has the same hobby as you do, and can talk about this, that, and the other and blah, the digital ink world.
now you have a completely different connection. blah, blah, blah.
But to switch gears a little: I know you’ve been Markus: Do you see those people communicate
very involved with things like eXtreme Program- more in writing, such as chats, or oral and aural? We get a lot of use out
ming going way back. I know you’re involved with of Whiteboard in
sizable organizations where you’re now trying to Dr. Neil: Both. With a large enough group of peo-
move some of those things that were tradition- ple, you’re going to start to see these different combination with
ally more of a “let’s do a standup in a room” ap- aspects of how people react. To some people, it’s MS Teams, especially when
proach, and now you’re helping organizations not so scary now that they’re on the other end of
doing that digitally. a screen rather than in-person. They feel more used with a digital pen.
comfortable talking to each other. And that’s in-
Dr. Neil: Most people have a scrum or an XP, like teresting too, because maybe that’s the kind of
standups or doing a retrospective, as regular person that would be better spending more days Markus: Which is why we’ve known each other for
things in their calendar, where they play a plan- working from home in the future, and maybe only ages.
ning game or work out what the next sprint is come into the office once or twice a week when
going to look like, or however they’re doing it. we go back to that normality. If we get back to Dr. Neil: That’s right! We first met in the Tablet
Those aren’t so challenging. It really wasn’t that that normality. Other people really miss being in PC era.
much of a big deal to get to “this is MS Teams the office. We just had a long weekend because
and this is how you use it and this is how you Monday was a holiday. And I know on Friday there Markus: That’s right. We worked on digital ink
use a whiteboard in Teams. This is how you share were some people, even though we’re already and the first handwriting recognition.
it.” Getting that kind of stuff up and running was seven months into this, who were going “well,
pretty quick and easy. what am I going to do on Monday?” Dr. Neil: I don’t think it was the very first [use of
handwriting], but it was the first on a Microsoft
In fact, there was one group of a couple of hun- Dr. Neil: Yes [laughs]. There is some of that. It’s tablet. On Windows XP. [Laughs] Microsoft had a
dred developers that moved from working in the also about teaching people that the informal ac- Pen for Windows that shipped on Windows 3.1 It
same building or same campus space. In the past, tivities are as valuable and sometimes more valu- was an additional product.
they could all, within a short walk, get to each able than the formal activities.
other. We were able to move them to an online Markus: It was a little bit akin to the Apple New-
virtual workplace within a week. They’re all tech- Markus: Do you promote or use specific tools for ton, probably.
nically capable, so obviously, they have a starting that or a mixture of tools? I know you’re using a
point. But a lot of them had not used the technol- lot of MS Teams. We use MS Teams and we also use Dr. Neil: Yeah. Kind of. It was in that era.
ogy that we’re now using every day. I think the Slack, Zoom, GoToMeeting, and others. We have a
more difficult aspect was trying to solve for how whole set of tools that we use and I often wonder Markus: You got a lot of use out of that, I take
people connect with each other more readily. if we shouldn’t standardize more or whether we it. [laughs]
should stick with letting people choose what they
Any group of people of any size is going to have feel they can be most productive with. Dr. Neil: Ummm....not so much. [laughs]. But it
some extroverts that have no problem with click- was interesting to me. I was attracted to it then
ing the call button and randomly just talk to Dr. Neil: I’ve become a religious follower of MS because I’m the kind of person who thinks better
people. And then there are some introverts that Teams. I was using Zoom and BlueJeans for a cou- with a pen in my hand than I do with my hands on
aren’t really comfortable contacting someone ple of other teams and I got frustrated with them, a keyboard. It helps me think about what’s going
by pushing a button and feel they want to know partly because the platforms failed to scale very on and get my ideas down if I can just sketch.
whether that person is available to talk to or not. quickly when suddenly everyone was working from
All the social cues that used to be there because home in the first couple of weeks. I just thought, We use Microsoft Whiteboard a lot. It runs on
you could look over and see that they’re at their “who really has the ability to cope with this level any Windows device and it runs on iPad. If you
desk or going for a coffee are gone. I always tell of scale in infrastructure?” It seemed, through trial have a pen, you get the extra bit of nice func-
them “just don’t worry about it. They can always and error, that MS Teams was the one. I know a lot tionality where you can engage. I think the other
not answer.” In fact, even while I’m talking to of people complain about it, but I really haven’t nice thing about Whiteboard is that, as different
you, I’ve got another screen here and someone had issues. I can quite easily swap among five ten- people are scribbling on the same whiteboard at
from another team has pinged me. I just said, ants each day, having multiple calls and conversa- the same time, you see their little icons popping
“I’m on a call.” Easy. tions, and just not struggle with it. up all over the screen.
You can track who’s doing what. You can see a Dr. Neil: I think that’s super interesting, espe- in Europe. Whatever. But productivity output is
bigger picture emerge as multiple people scribble cially in the kind of businesses that you and I not necessarily proportional to that. Whatever
down. You can divide the page into columns and are in, which are really creative businesses. Cre- the case might be, we think of it as a 40-hour
people can enter stuff in their own columns, or ative output isn’t something that you measure week. When you really think about it, the aver-
however you want to do it. You can create notes by how much time is spent sitting in front of age worker probably spends about 60 hours on
and move them around on the page. I found that the screen. One of the most incredible develop- things related to work, whether it’s the fact that
a very useful free-form tool in the same way I’ve ers I ever worked with probably spent more time you had to drive in to work or take an hour for
always liked having a whiteboard in a working on his back on a sofa than he did typing on the lunch. There was really no reason to be in town
space when I’m in the same room as someone. computer. He did a lot of thinking and then he for lunch other than work. Or the fact that we
It encourages that wider conversation. I think would do some furious typing and then he would had to drop the kids off at daycare. That takes an
sharing screens fluidly and being able to share go back to thinking. And his code was insanely hour a day. I think 60 hours is much closer to the
screens between different people in the con- good, insanely high quality, with very few defects real number that people spend “at” work. If you
versation is also very powerful. People want to ever found in the code that he wrote. But he’s not say, “let’s reduce that to 50, but we get an extra
share, whether it’s a new UI they’re designing or someone you’d measure based on how many lines 10 productive hours out of you,” that’s a win-win
they want to have a conversation around some of code he’d written or how many hours he spent for everyone.
plan they’ve put together. Just being able to do in front of the keyboard.
that in Teams has been powerful. Dr. Neil: Yeah. Although again, it depends on
You’re not typing a document that you already the kind of work you’re doing. There’s work with
Bringing in guests is also very powerful. Know- know or that’s being dictated into your head. intention where I’m actually sitting here at my
ing that you can lock MS Teams down to people You’re thinking of new ways of solving problems. desk, thinking about a problem, trying to fix
within your organization, but you can have teams That’s a very hard thing to measure in hours any- something, trying different things, coding dif-
where you can bring in guests in a controlled way. If you’re of the mindset that you need to ferent tests, making them pass. And then there’s
fashion is another aspect of it. There are lots have people sitting behind their desk for a cer- “sleep programming,” if you want to call it that,
of pieces of the puzzle that connect together to tain period of time, that’s probably based on where I’m away, but my brain hasn’t totally
make what I’ve found to be a very useful toolkit some incorrect assumptions to start with. Even switched off. Although I’m not consciously think-
that MS Teams has presented. with pure data entry, you’re not really getting the ing about this particular problem I’m trying to
most value out of workers that way. solve, my unconscious is still working through it.
Markus: I believe you can use the Whiteboard Software development, if you’re really into the
product whether you use Teams or not, is that Some of the teams I’ve been working with—and project that you’re building, is the kind of thing
correct? I like to think that it has to do with me support- that you might wake up at two in the morning
ing them over the years—had in place a bunch and go “that’s what I need to do!”
Dr. Neil: Yes. The Whiteboard product isn’t at- of measurements that help them understand how
tached to Teams. It’s a separate product. It’s at- their dev team was doing. It could be things like So what do you do? Do I bill my customer from
tached to Active Directory. Most of the organiza- defect counts. You know, very simple high-level 6:00 p.m. until two in the morning where it was
tions I work with are enterprise-scale organiza- things like “how many defects do we have report- ticking in the back of my head even though I
tions. They have their own Office365, so we work ed a month?” or “how quickly are we fixing these played the guitar and watched TV and put the
with those inside their firewall, logged in as an defects?” or “what’s the severity of the defect?” kids to bed or whatever? Do you bill for that as
AD under their domain. Is it severity zero where the whole system doesn’t well? Clearly something was happening in the
work? Is it severity 12 and it really doesn’t mat- back of your brain that made you wake up at two
Markus: Most people already have a license for it ter if no one ever fixes it? Just measuring those in the morning with that sudden breakthrough
because it’s part of Office. things is a good starting point, but there are idea that’s worth a lot. It’s interesting that so
other things you can measure. many companies measure software development
Dr. Neil: Right. Microsoft made big move to make by those traditional 40-hour weeks.
it free for everyone during this period. So that’s Teams that already had a lot of measurement
made it useful too, in that if I have a team that’s in place when they moved into work from home I’ve had lots of conversations with different prod-
not necessarily hooked into the Microsoft ecosys- transitioned quite smoothly because their pro- uct teams and senior leaders about this over the
tem, I can add them as guests into my domain ductivity was very clear. We saw some spikes in years, because I think it’s very broken. We want
and bring them in to conversations. productivity initially, which was interesting. solutions, outcomes. It’s not a new thing. Google
People were like “oh, well, I don’t have to com- has been doing it for a very long time. Actually,
Markus: That brings us right back to people work- mute now. I’ll just do an extra half hour or an it originally came from Andy Grove and Intel. The
ing from home and wanting it to stay that way, extra hour. I’ll be sitting in my pajamas coding, “objectives and key results” concept, where you
which gets into discussions such as how you know but who cares?” And all of that turned out to be have high-level objectives for your year and you
what your employees are up to at what point in a positive. have a set of key results that you’re measured on,
time, and then how much do you want to know maybe quarterly. If you have the kind of business
and how much should you know, and how do Markus: I find that part highly interesting, be- where you can set out those bigger goals and
you monitor productivity and productivity versus cause we tend to think of a work week as roughly have some measurements over time, you can give
hours worked. What do you make of all that? 40 hours. A little more in the US, a little less people much more freedom because they under-
stand “this is what I’m being measured on” and such as “who am I collaborating with?” or “who prior to this situation, because you were already
they can go away and think about it. am I talking to?” Also, how much time have I moving to a set-up where you wanted the ability
spent in meetings versus my focus time? The to hire the best people no matter where they were
If that means the best way for them to do that is question is: How do you measure those things? located. You were in Hawaii and you had people
to lie on the floor and stare at the ceiling for two in Texas and in Europe, and so you were already
weeks while they think about the problem and Markus: And how well do those tools integrate all moving to this more distributed set-up.
then furiously solve something and then lie on the things you do versus just the Microsoft view
the floor for two weeks and furiously solve some- of the world? Markus: It was out of necessity back then as well,
thing, that’s fine. And there are different types because we simply wanted to hire good people
of people who’d prefer to slowly plod their way Dr. Neil: As we start getting more of this into from around the world and certainly across the
through the activity to get to those results. Mea- dashboards, we can start rolling it up into big- US, and people were less and less excited about
suring those goals and the success of reaching ger pictures of what people are doing. It will al- moving to Houston.
those goals is much more valuable than measur- low us to understand that “oh, this person is a
ing how many lines of code he wrote or was she communicator and look how much time they’re Listen, I used up a lot of your time already. I
typing today or did she open Visual Studio today? spending, helping other people online in Visual don’t want to take away from your productivity,
Who cares, as long as you’re getting the result Studio.” In Visual Studio Live Share, I can track although maybe in the back of your mind, you’re
that you’re looking for? Maybe you didn’t open how many people in a dev team use it, how many thinking about other development problems and
Visual Studio for two days, but then maybe you hours they used it, and what kind of activity they solved them by now. [laughs].
coded solid for 70 hours. How do you measure did. Am I seeing better results now that they’re
that? There are people who work that way. I think using Live Share? I think there’s a lot of inter- Dr. Neil: [laughs] Actually I’ve just finished this...
productivity is a very difficult thing to measure. esting stuff that we already have the ability to no. Just kidding.
You need bigger goals and you need different capture. As we start doing that, we’ll find other
levels of measurement. The teams that did well aspects of what we’re doing that are just as im- Markus: You and I used to get together in person
in their initial move to work-from-home were the portant. all the time and have great discussions. I miss
teams that had more things being measured. that. Hopefully we’ll be able to get back to that
again.
Markus: That’s definitely something that will be
interesting to watch over the next few years. You The reality is that when we Dr. Neil: I think we will. It’s going to change and
do need to measure as a business. We can’t just it’s probably going to be a lot less often going
trust all workers to be great. You need to evalu-
all worked in a single office, forward, because a lot of us are being a lot more
ate it and make sure you get the kind of results I had less of an idea of how cautious about travel too.
that you want. As a business owner, I don’t have productive my team was
any silver bullets at this point. I certainly have a Markus: Maybe. Maybe we’ll start valuing those
pretty good feel for how some of my people are than I do in a distributed, travel opportunities more as well. Maybe my days
doing at home. virtual setup today. of 48 hours in Australia can change to once a year
and stay a month or two instead.
I think it depends a lot on the roles people play.
For me, at least as a manager, keeping track is Dr. Neil: I’ve often valued spending more time in
much easier with creative people such as soft- Markus: One aspect that I find interesting is that places than just going for a week or two weeks.
ware developers. I also run other businesses—a people tend to think that because of the situa- By being somewhere for two or three months, you
magazine, an escrow company, and a few things tion we’re now in, all of this is going to change get a lot more value than just rushing off again
like that. How do I evaluate the performance of because everybody wants to work from home, and like we used to do.
my customer service department working from that reduces the ability to manage and oversee.
home? By customer satisfaction, probably, but But when I think back to the days where we liter- Markus: It’s definitely true. Well, anyway, thank
then how do I measure that whole interaction ally worked just a brick and mortar company with you very much for your time. This was an excit-
exactly? I think that’s an area where there’s huge everybody in one building across multiple floors ing talk.
potential for optimization for businesses going and everybody went to work in the morning in a
forward. very traditional set up, I probably had less of an Dr. Neil: Absolutely. Awesome.
idea as to how productive people were or whether Thank you very much too.
Dr. Neil: You use Office365, right? Do you get a they were browsing the Internet while at work
report every two weeks or a monthly report of than I do today. Markus Egger
your activities in Office?
Dr. Neil: Yeah. I think that’s true. A lot of that
Markus: Yeah. depends on how your team engages. It’s about
whether they’re the kind of people who will reach
Dr. Neil: I think those kinds of things are already out to you because you’re not in the office. I think
starting to be built into the tools. You get things your culture had already started to adapt to that
TAKE
AN HOUR
ON US!
Does your team lack the technical knowledge or the resources to start new software development projects,
or keep existing projects moving forward? CODE Consulting has top-tier developers available to fill in
the technical skills and manpower gaps to make your projects successful. With in-depth experience in .NET,
.NET Core, web development, Azure, custom apps for iOS and Android and more, CODE Consulting can
get your software project back on track.
Contact us today for a free 1-hour consultation to see how we can help you succeed.
codemag.com/OneHourConsulting
832-717-4445 ext. 9 • [email protected]
codemag.com
ONLINE QUICK ID 2009101
you learn by doing. .NET, as we know it, has had a good run. you can download and install as well as use their learning
It’s been 18 years. resources to get you up and running.
Figure 1: VS Code automatically installs a context menu choice for easy launching from the File Explorer.
Figure 2: VS Code provides ready access to release notes for the version installed on your workstation.
you have the things you plan to use through extensions. It’s
also fair to say that how you approach the VS Code tool will
be quite different from how you approached Visual Studio.
I prefer VS Code because it eliminates the clutter of unhelpful Figure 4: For many of the things that are automatically available in Visual Studio, you must
abstractions. Do I find myself handing some things manually install an extension in VS Code.
and working with the command line more? I absolutely do. I
don’t see that as taking a step backward. Rather, I see it as re-
fining how I perform my work in a way that allows me to focus
directly on the work. To that end, wherever you choose, create
a folder named UnitTestingInNETCore for your workspace. Once
you’ve created the folder, navigate to that folder in File Explorer,
right click, and select Open with Code, as illustrated in Figure 1.
If you’re used to working with Visual Studio, the VS Code en- fishing rod. You already know how to fish. You just need
vironment looks quite different. Instinctively, you may start guidance on how to use a different tool.
clicking around looking for things that automatically appear
in Visual Studio. More likely than not, you won’t find what One of the things that grabs attention is not what’s in VS
you’re looking for and this may frustrate you. Be patient! Code, but what isn’t. There’s no clutter. VS Code’s entire prem-
Think of this exercise as teaching yourself how to build a ise is based on letting you choose what you need for your proj-
Figure 6: Many of the tasks you carry out in VS Code, like creating new projects, are done via a PowerShell Terminal instance.
Figure 8: Each project is contained in its own folder. To perform tasks, whether it’s to add a NuGet Package or build/
compile, a terminal must be available.
ects. That, coupled with the different context of Visual Studio, is to undertake interactive unit testing in VS Code like you do
might make you feel lost. What now appears in the left-hand in Visual Studio. How do you do that if the feature doesn’t ex-
portion of the editor is the Explorer. In Visual Studio jargon, ist? The answer is found in asking the right question. The real
it’s kind of like the Solution Explorer. But it’s more like the File question is whether there’s an extension. In fact, there is an
Explorer. And if you start right-clicking project artifacts like extension and in the next step, you’ll install it.
you would in Visual Studio, you’ll quickly understand!
Figure 10: The OmniSharp Extension enables VS Code to understand how to work with C# and compile files.
Figure 11: With OmniSharp installed, you can build C# projects in VS Code.
Figure 14: Under Settings\Extensions\.Net Core Test Explorer, you need to set the Test Project Path. If you follow a naming
convention, wildcards can be used to cover multiple test projects.
A command you’ll want to be well acquainted with is dotnet with VS Code, we’re much closer to what is going on. With fewer
new: (https://docs.microsoft.com/en-us/dotnet/core/tools/ abstractions, it’s easier to understand what’s going on when
dotnet-new). In Visual Studio, when you want to create a new you have to fix a problem. How many times have things just not
solution or project within a solution, that task is typically car- worked in Visual Studio without a clue as to what exactly went
ried out via point-and-click operations against a menu option. wrong? Those problems are less likely to occur with VS Code.
Although there are some operations in VS Code carried out in
that manner, many will be carried out via the command line. Figure 7 illustrates how to create a new class library. In the
To some, that may seem like a step backward. In my opinion, terminal, type dotnet new classlib -n Math.
public static int
Add(int pOne, int pTwo) => (pOne+pTwo);
Now that you have a unit test project with a test, you should
be able to see the test in the test explorer, right? Wrong!!
Figure 13 illustrates a cryptic message.
If you click the arrow next to the test name in the explorer,
the test runs. Figure 15 illustrates a passing test run.
Figure 18: When debugging tests, you have access to watched variables, breakpoints,
Before you can write unit tests against your code, the unit and the call stack.
test project needs a reference to the math class library proj-
ect. The process for this, in concept, is the same as Visual a developer, retain control because the environment is doing
Studio. The concrete steps to implement, however, are quite less for you behind the scenes. If something goes wrong, the
different. In VS Code, you often need to go into the csproj file cause and the cure become that much more apparent. Figure
and edit the XML directly. This is typically not the case in Vi- 16 illustrates how to add the project reference.
sual Studio. This may seem like a step backward. In my opin-
ion, working directly with project artifacts means that you, as Figure 17 illustrates a simple test with a breakpoint.
Figure 20: Tests can easily be run from the command line. VS Code provides quick access to details on failing tests through
interactive and intuitive prompts.
Figure 18 illustrates the breakpoint being hit in an interac- wish to add. I think you’ll find that VS Code isn’t really a prim-
tive debugging session. itive tool when compared to Visual Studio. Sure, Visual Studio
has a lot of features. How many of them do you really use?
Finally, Figure 19 illustrates a passing and failing test. And if you use refactoring tools like Resharper or CodeRush,
performance can often be an issue. You won’t find versions
If you prefer to run tests from the command line, you can of Resharper or CodeRush in VS Code for the simple reason
easily do that. The process for that is illustrated in Figure 20. that you don’t need them; there are several good (and free!!)
refactoring extensions available. Some are better than oth-
ers. Try them by kicking the tires and find the one that works
Conclusion for you. Give VS Code a try. I think you’ll find as editors go,
Writing and interacting with unit tests in VS Code is really no it’s well suited to the task. And if you like working on a Mac,
more difficult than how it’s done in Visual Studio. VS Code is there’s a native version of VS Code for Mac as well! Enjoy!
just a tool and like any tool, you simply need to understand
how to use it. You’ll find that through extensions, you can add John V. Petersen
many features. The key is that you control which features you
(Continued from 74) first words in the Agile Manifesto that codified
principles 19 years ago says it best:
collaborative culture. There’s a responsibility to lift
people up. It’s one thing to talk. It’s another thing Sep/Oct 2020
to walk it and live the sermon. Volume 21 Issue 5
We are uncovering better ways
It’s not enough to have people who are willing of developing software by doing Group Publisher
to teach. There needs to be an environment that Markus Egger
it and helping others do it.
is conducive to giving people the opportunity Associate Publisher
to learn. It’s not about top down vs. bottom up. Rick Strahl
It’s about meeting in the middle. If it sounds like Editor-in-Chief
liberal democracy, that’s because that’s precisely The challenges faced by the NT team were no differ- Rod Paddock
what successful organizations practice. And by do- ent from those faced by other teams, and the Show-
Managing Editor
ing so, they avail themselves of the ability to take stopper book provides insights into how the team Ellen Whitney
advantage of wisdom its personnel have. confronted what were many serious issues. NT lead-
ership (specifically Cutler himself) recognized the Content Editor
Melanie Spiller
propriety of testing by non-developers. That was, to
Read Showstopper! a large degree, a very ego-driven personality who Editorial Contributors
Otto Dobretsberger
In 1993, an amazing piece of software was finally set aside his ego for the benefit of the project that Jim Duffy
available to the public: Windows NT. NT was com- was a creation of his vision and realized by his drive. Jeff Etter
prised of millions of lines of code amongst 40K files, Mike Yeager
written by a team of about 250 people over a period Eight years after NT was released, 17 notable and Writers In This Issue
of about four years. As somebody who was an early famous software developers met at the Snowbird Richard Campbell Otto Dobretsberger
NT adopter, I remember well the fanfare for its re- Resort in Utah to craft the Agile Manifesto and its Markus Egger Kevin S. Goff
Joydip Kanjilal Vassili Kaplan
lease. At the time, I knew nothing of what it took to supporting principles. We’re still trying to figure Stefan Landvogt Sahil Malik
build NT. As it turns out, it took many things: money, it out 19 years later! How do we learn? By doing. John V. Petersen Paul D. Sheriff
careers, egos, mental health, marriages, etc. That is In other words, we practice the craft, and in that
Technical Reviewers
what the book “Showstopper! The Breakneck Race to regard, what software developers do is no differ- Markus Egger
Create Windows NT and the Next Generation at Micro- ent from what any other professional does. Practice Rod Paddock
soft” by G. Pascal Zachary is all about. I profess that implies skills development and continuous learning.
Production
it’s been in my library for quite some time, but I just We learn by doing and our feedback loop is empirical Franz Wimmer
finished reading it. Originally published in 1994, it’s a data. In my opinion, good developers take the time King Laurin GmbH
book I wish I’d read years before. It’s the kind of book to understand and appreciate history, and then they 39057 St. Michael/Eppan, Italy
that’s worthy of many readings during your career. learn from those experiences and go on from there. Printing
Fry Communications, Inc.
My biggest takeaway from the book is the reinforce- Delivery is a feature. We can’t analyze a problem 800 West Church Rd.
Mechanicsburg, PA 17055
ment that there are no new problems and that the to death. We must be pragmatic. We must avoid
past is just a prologue. There are lots of great in- perfection becoming the enemy of progress. That’s Advertising Sales
sights into the challenges of managing large teams, not a license to just throw something over the wall Tammy Ferguson
832-717-4445 ext 26
complex features, and testing. What makes Show- for the sake of delivery. Tools and techniques come [email protected]
stopper such a poignant read is how it focuses on and go, but principles endure. That was the gist of
the one individual who led the NT team and his my technical article on Unit Testing in VS Code (in Circulation & Distribution
General Circulation: EPS Software Corp.
journey as a developer that started in the early this issue). VS Code is quite different from Visual Newsstand: The NEWS Group (TNG)
1960s. As of today, David Cutler is nearly 80 and is Studio. If you take on VS Code with Visual Studio Media Solutions
still a distinguished technical fellow at Microsoft. expectations, you’ll flounder. On the other hand, Subscriptions
Here is a somewhat recent article from 2016 that if you consider, at an abstract level, what you’re Subscription Manager
highlights Cutler’s and his cohorts’ history: https:// trying to accomplish, and apply testing principles; Colleen Cade
news.microsof t.com/features/the-engineers- principles that transcend specific tools, there’s no [email protected]
engineer-computer-industry-luminaries-salute- longer an impedance mismatch between context US subscriptions are US $29.99 for one year. Subscriptions
dave-cutlers-five-decade-long-quest-for-quality/. and your mode of problem solving. The solution outside the US are US $49.99. Payments should be made
will make its presence known and will just fall into in US dollars drawn on a US bank. American Express,
MasterCard, Visa, and Discover credit cards accepted.
place. And if it doesn’t, it’s time to cut bait and
Never Stop Learning consider a change in approach. Often, that change
Bill me option is available only for US subscriptions.
Back issues are available. For subscription information,
This is not the same thing as being on the ham- requires a refined problem definition, a better e-mail [email protected].
ster wheel of technical churn where we trot out understanding of the problem, or a better under- Subscribe online at
and deploy new things for the sake of it! I’ve lost standing of the tooling, just to name three possi- www.codemag.com
track of my own past efforts to learn enough about bilities. How things work as they do is subordinate
CODE Developer Magazine
something just to realize that it’s better to leave it to why things work as they do. When you focus on 6605 Cypresswood Drive, Ste 425, Spring, Texas 77379
on the shelf, never to be touched again! The issue why, you necessarily will focus on base principles. Phone: 832-717-4445
is the never-ending quest to somehow leverage
the good without encountering the not-so-good. Why do base principles always apply? Because
How do we keep control of a large project and, at principles endure. And why is that? Because there
the same time, keep control of what today we call are no new problems.
the work-life balance? In striking the balance, how
do we decrease defects (showstoppers), increase John V. Petersen
features, and increase delivery velocity? The very
intrinsically difficult. There are several items to today. It may very well be that what’s being faced hand, they’re different. The contradiction can be
check off first: today is more serious than what was faced in 1918. resolved if context is considered. On one hand,
That, however, is a different issue, one of scale. being a Luddite isn’t good. On the other hand,
• Do I understand the problem (have I suf- technical churn that’s always in the favor of what
ficiently broken it down)? Another way to illustrate the point is by way of fic- is perceived as being the latest and greatest isn’t
• Have I attained sufficient competency to tion writing. Christopher Booker’s 2004 book “The good either. To be the greatest at anything im-
both practice my craft generally and in a Seven Basic Plots” sets forth that proposition in a plies that there’s empirical evidence to support
specific context? very straight-forward way. The seven basic plots are: that. New things, by their very nature, lack em-
pirical evidence. That’s why we should always test
In the law, when an issue is analyzed, we determine • Overcoming the monster first. Another quote for the pile: Trust but verify.
whether there are threshold issues that must be • Rags to riches
first addressed. For example, if you slip and fall in • Tragedy
a store, can you recover damages? That depends on • Comedy
Wisdom: Where Knowledge
whether the shopkeeper was negligent. Negligence • The quest Meets Experience
depends on whether the shopkeeper had a duty to a • Voyage and return It’s important not to confuse the use case with the ac-
foreseeable plaintiff to exercise reasonable care. If • Rebirth tual problem. For example, the need for a new daily
reasonable care was exercised, that settles the mat- sales report isn’t the problem; it’s a feature request.
ter. The issue of damages is irrelevant. In fact, we can break these down further to ris- There are many subordinate issues that need to be ad-
ing and falling. Sometimes the story is one or the dressed to achieve this goal. At its core, the request is
Software development is no different in that we other. And sometimes it’s a combination of the about data retrieval, which, in turn, has (among other
need to always break things down to their constitu- two, multiple times in different sequences. For all things) rendering, performance, and security con-
ent parts. In other contexts, we call this root-cause the twists and turns and factual differences, when cerns. As we bore into the details, we eventually real-
analysis. In other contexts, we employ what is known we break them all down in a coding project, there ize that for each thing we encounter, there’s a solution
as the scientific method. We learn by observation are only a few categories that we end up with. Any that’s been employed before. One question is how far
and testing. From that, empirical data is produced software does at least one and up to four things: into the weeds we need to go to break the problem
that provides the evidence for us to be able to make create, retrieve, update, and delete data. down to its constituent parts. There’s no precise an-
informed decisions. Whether we, in fact, make in- swer. The generic answer is to dig as deep as is neces-
formed decisions, depends on whether we follow the Whether 50 years ago or today, we have problems sary and no deeper. What does that mean? It means
evidence and whether we respect the science. That’s to address with technical solutions. To do that, that you keep digging until you hit familiar territory.
the irony of our industry. Logic and reason are at its we write, test, and deploy code. That’s what we
core. But too often, those two things are the first do. At a foundational level, software creates, re- If, after digging for a while, nothing is familiar or
casualty of problem solving. The scientific method, trieves, updates, and deletes data. These are the isn’t understood, look in the mirror. You may lack
in one form or another, traces its roots back many CRUD operations and that is what the software the necessary experience to deal with the issue. You
thousands of years: i.e., principles endure. does. How the software does what it does, that’s need the wisdom to know when you don’t know. And
indeed different. Where we used to rely exclusively if you don’t possess it, collaborate with someone
There are many phrases we employ today that on relational databases and SQL, today we may who does. Anything else and you’re just burning
convey these meanings: What’s past is prologue rely on NOSQL and unstructured solutions. Very cycles with no benefit. This is where a culture of col-
and Those who forget the past are condemned to different things, to be sure. But at a fundamental laboration and inclusiveness matters. No one person
repeat it. These quotes are attributed to William level, we’re talking about the same thing: key val- has all the answers. And yet there are those among
Shakespeare and George Santayana, respectively. ue pairs. That’s what JSON is. That’s what XML is. us who seem to instinctively know how to break
And yet often, JSON is regarded as a newer, more down and solve problems. In other words, there are
Whether it be politics, foreign relations, domestic modern thing and XML is regarded as old. In .NET those who know that boiling the ocean is an exer-
policy, human nature, etc., the lesson is clear; al- Core and VS Code, we have the appsettings.json cise in futility. Knowledge comes from learning, not
though there may be some new and novel aspect to file. It’s just a configuration file, like app.config instinct. Those of us who have the knowledge and
any individual thing, taken all together, the prob- or the ini files we employed in days past. They’re experience have a moral, ethical, and professional
lem has been encountered before. Take COVID-19 as different things and, at the same time, the same obligation to share it so that we can pass it on, be-
an example. The analog used to understand it is 100 things. What’s the threshold issue? It’s context. cause once upon a time, somebody helped us. That
years old: the 1918 flu pandemic. That’s not to say isn’t enough, though. Organizations and leadership
that the two are the same. They’re not. But there Another phrase that comes to mind is: The only have their roles to play as well. They must foster a
are many similarities and, at a root level, the same constant is change. It seems like a paradox: On
core issues faced in 1918-19 are what’s being faced one hand, things are the same; on the other (Continued on page 73)
Keep up with the pace of Validate skill levels with Measure progress towards
change with thousands of assessments that take personal objectives and
expert-led, in-depth courses. 10 minutes or less. learning goals.