Code - May June 2024
Code - May June 2024
MAY
JUN
2024
of a Database
Developer
We will send an expert to your office to meet with you. You will receive:
1. An overview presentation of the current state of Artificial Intelligence.
2. How to use Al in your business while ensuring privacy of your and your clients' information.
3. A sample application built on your own HR documents - allowing your employees to query
those documents in English and cutting down the number of questions that you
and your HR group have to answer.
4. A roadmap for future use of Al catered to what you do.
CONTACT US TODAY FOR A FREE CONSULTATION AND DETAILS ABOUT OUR SERVICES.
codemag.com/ai-services
832-717-4445 ext. 9 • [email protected]
TABLE OF CONTENTS
Features
7 CODE: 20 Years Ago 46 Stages o f Data: The DNA o f
Markus c o n tin u e s his re fle c tio n on w h a t th e com pany, th e m agazine,
and th e in d u s try have been up to fo r th e la s t th re e decades.
a Database Developer, Part 1
Markus Egger W hether yo u 're g o in g to an in te rv ie w as th e a p p lic a n t o r th e
in te rv ie w e r, y o u 'll be glad t h a t Kevin came up w ith th is c o lle c tio n
o f th e th in g s y o u o u g h t to know i f y o u w a n t to succeed.
10 Async Programming in JavaScript Kevin Goff
S a h il shows yo u how to c o o rd in a te th e m u ltip le processors th a t
yo u need to do a n y th in g in to d a y's h ig h -p a ce d c o m p u tin g w o rld .
Sahil Malik
59 From SOAP to REST to GraphQL
I f y o u need to store, m ove, o r access d a ta , y o u 'll need to know
how to make sure t h a t a ll o f y o u r system s ta lk to each other.
16 M anipulating JSON Documents J o y d ip e xplains how SOAP, REST, and GraphQL co m b in e to make
t h a t a sm ooth process.
in .NET 8 Joydip Kanjilal
Ja va S crip t O b je ct N o ta tio n (JSON) can help y o u c o n fig u re s e ttin g s
and tra n s fe r d a ta , b u t i t re a lly shines w hen i t comes to c re a tin g
and m a n ip u la tin g docum ents in .NET 8. Paul shows y o u how.
Paul Sheriff
Code Compilers
38 Preparing for Azure w ith
Azure Migrate Application
and Code Assessment
Your com pany is s w itc h in g to p la tfo rm -a s -a -s e rv ic e (PaaS) from
on-prem ises and y o u need to re -p la tfo rm y o u r a p p lic a tio n s .
Mike shows yo u how to make t h a t happen using Azure M igrate
A p p lic a tio n and code assessm ent.
Mike Rousos
Unfinished Paintings
I spent last weekend in rainy (normally sunny) Southern California. During this trip, I managed to corral
the kids into going to the Academy Awards Museum. There, we came across a set of drawings from the
original Disney animated film The Little Mermaid (Figure 1). From what I could deduce from the drawings,
I believe they are what are called key frames. tarps like you can buy a t W almart), I saw street So being the fresh-faced coder, how could
In anim ation, the artists draw key frames, which posters, statues, and oth er paintings from his I learn to b e tte r my craft? I did th is several
represent different transitions in the animation extensive set o f works. One o f these works ways. I read every book I could get my hands
and are then passed onto other artists who f ill in stood o u t to me. Figure 2 is an image o f an on, I w ent to the "b ig " c ity o f Portland where
the frames between the keys. As I described what unfinished work started n o t soon before his un I discovered knowledge heaven in the form o f
these frames were for to my kids (and a random tim e ly death. I spent tim e studying the image, Powell books, and, fina lly, I read every com
onlooker), I discovered mentally why I'm fasci looking a t i t from d iffe re n t angles and vantage puter magazine I could get my hands on. The
nated w ith such works. I'm fascinated by them points. I trie d to picture Keith w orking on th is articles th a t I really to o k a Liking to were the
because they're unfinished. I find th a t these a rti p a in tin g in his studio in the flo w o f a rtis tic cre ones where the authors explained the process
facts o f the creative process give me insights in to a tiv ity . This image to o k me in to a creative flo w o f how they achieved a solutio n. Using a rt as
the mind o f the a rtist creating them. state. A ll from an unfinished pa in ting . a metaphor, they to o k me through the rough
drawings, pencil sketches, rough demos, base
I Love the rough drawings, erasure marks, rough For some reason, I've always loved works from coats, d e ta il work, and fin a lly, a finished
lines, and a ll the th in g s th a t show how the a rt a rtists th a t are incom plete works versus com w orking solutio n. I was w atching techno a rt
is t works. This to o k me back to another mu pleted works. This is my in n e r creator coming ists take me through th e ir process from u n fin
seum v is it. out. I t takes me back to the earliest parts o f ished to finished work. This is my process to
my career where I was the "Lone w o lf' devel- th is day.
Last year I was lucky enough to attend an exhi op er/n etw ork admin fo r a sm all resort in Cen
b itio n o f the works o f Keith Haring a t the Broad tra l Oregon. This was back in the Late 80s when Many o f the unique solutions I've b u ilt over
Museum in downtown Los Angeles. I've been a there was no in te rn e t Like we have now. There the years come from a process like th is one.
follow er o f Keith's work fo r decades now and were no GitHub repositories, no code blogs, I'm tasked w ith seeing i f an idea m ig h t work.
d o n 't miss any chance to see collected exhibits no www.stackoverflow.com . Nope. There were For instance, many years ago, I was tasked
o f his work. This e x h ib it stood o u t to me as crappy 1200 or 2400 baud modems by which we w ith bu ildin g a solution where we embedded
I saw works and materials he'd used th a t I'd reached o u t in to the world to gather our knowl code in M icrosoft Word documents th a t gave
never read about or witnessed. I saw fu ll blown edge from forums like CompuServe and Genie. I t users the a b ility to create dynamic scripts fo r
murals painted on camping tarps (yes ,camping was the dark ages. LOL. call centers. I started th is process to see i f I
could embed code in to a work document. This
was my rough sketch. I then too k the o u tp u t
from th a t docum ent and b u ilt an HTML-based
scrip t using the metadata embedded in the
docum ent, another sketch. I then combined
these tw o to g e th e r in to a rough demonstra
tio n fo r the clie n t. The c lie n t liked w hat they
saw, and we w ent through the process repeat
edly u n til we had a good w orking so lu tio n . This
code lasted nearly 10 years u n til a new solu
tio n was im plem ented. I t enjoyed many years
o f success, a ll o rig in a tin g from a rough sketch
o f code.
6 Editorial codemag.com
ONLINE QUICK ID 2405011
tu rb u le n t tim e. The dotcom bubble had burst, and the projects we were w orking on in the consulting and custom
glory days o f technology seemed to be over. Was the in app dev side o f the business w eren't classic dotcom com
te rn e t really a ll i t was supposed to be or was i t ju s t a panies. Also, we'd started CODE Magazine in the Spring o f
passing fad? I t was hard to say. 2000 and focused prim arily on the new world o f software
developm ent th a t M icrosoft was generating. The Java pro
gramming language was o f in te re st to a Lot o f people b u t
The Aftermath of the Dotcom Bubble had some issues th a t were, as o f the n, unaddressed, and
One o f the main catalysts fo r the dot-com -bubble bursting one way to fix i t was Microsoft's approach o f re-in ven t
was the overvaluation o f many internet-based companies ing the language in a top-secret project headed up by
th a t had little or no profits b u t huge expectations. Inves language-guru Anders Hejlsberg, codenamed "C ool." (This Markus Egger
tors poured money in to these ventures, hoping to cash in became C#, and yes, C# is s till cool. You may have seen [email protected]
on the next big th in g , b u t many o f them turned o u t to be the T -shirt).
unsustainable or unprofitable. Some o f the most notorious Markus, the dynamic
examples o f dotcom failures were Pets.com, Webvan, eToys, C# became a key com ponent o f the then nascent .NET founder of CODE Group and
CODE Magazine's publisher,
and Boo.com, which burned through m illions o f dollars in ecosystem, which did away w ith the concept o f the pro
is a celebrated Microsoft
a m atter o f months before going bankrupt. The collapse o f gramming Language driving everything and instead cre
RD (Regional Director) and
these and other companies sent shockwaves through the ated a developm ent framework th a t could be used equally
multi-award-winning MVP
stock market, w iping ou t billions o f dollars in value and from various languages. This was a concept th a t jiv e d
(Most Valuable Profession
causing many investors to Lose confidence in the sector. very much w ith w hat we believed a modern software de
al). A prolific coder, he's
velopm ent magazine should be ta lk in g about, and thus
influenced and advised top
The world o f software development wasn't immune to the CODE Magazine found its e lf in a sweet spot o f sorts. Other Fortune 500 companies
effects o f the dotcom bubble bursting. Many software magazines, Like Visual Basic Programmer's Journal, Fox and has been a Microsoft
developers who'd been hired by dotcom startups found Pro Advisor, and many more, suddenly d id n 't look so hot contractor, including on
themselves o u t o f work when th e ir employers w ent under. anymore. A Lot o f th is w asn't a coincidence. A fte r all, the Visual Studio team.
Some o f them had to accept Lower salaries or switch ca we'd long been partnering very closely w ith M icrosoft— I Globally recognized as
reers, and others tried to start th e ir own businesses or jo in worked fo r the Visual Studio team as a contractor on va ri a speaker and author,
more established companies. The demand fo r web develop ous projects— and we were strong believers in these new Markus's expertise spans
ment skills decreased, as many companies scaled back or concepts. A rtificial Intelligence (A l),
canceled th e ir online projects. The failure o f many do t .NET, client-side web, and
coms also raised questions about the v ia b ility and quality A ll these goings-on meant th a t we were somewhat pro cloud development, focus
o f some o f the emerging web technologies and standards, tected from the dotcom mess. Yes, we also lo st some cus ing on user interfaces,
such as Java, XML, and HTML. Some critics argued th a t tomers, and the pool o f p o te n tia l new customers shrank. productivity, and maintain
these technologies were overhyped and underdelivered, We had to tig h te n our belts a b it, b u t overall, we came able systems. Away from
and th a t they weren't suitable fo r building complex and through i t a ll reasonably w ell. I remember i t as a tim e work, he's an enthusiastic
windsurfer, scuba diver,
reliable applications. Others defended these technologies th a t was p a in fu l fo r us, b u t n o t to an e xiste n tia l level.
ice hockey player, golfer,
and claimed th a t they were s till evolving and im proving, And despite a ll the in te rn e t disillusionm ent, we remained
and globetrotter, who
and th a t they would eventually prove th e ir w orth. s to u t believers th a t i t w asn't the in te rn e t th a t was the
Loves gaming on PC or
problem b u t rather the problem was the idea th a t the
Xbox during rainy days.
Despite the challenges and setbacks th a t the dotcom bub in te rn e t made economic fundam entals obsolete. In other
ble bursting posed for the software industry, i t also had words, we considered i t crucially im p o rta n t to push fo r
some positive effects. I t forced many companies to rethink ward w ith in te rn e t-re la te d technologies. As a M icrosoft-
th e ir business models and strategies, and to focus more on focused organization (and a M icrosoft partner), th is
customer needs and satisfaction, rather than on growth meant m ainly focusing on ASP.NET as the backbone o f
and hype. I t encouraged more innovation and experimenta alm ost a ll web applications th a t we wrote. We had largely
tio n as some developers sought to create new and better ignored earlier versions o f ASP, b u t then there was th is
solutions for the web. I t also paved the way fo r the emer young kid o f a program manager s tra ig h t o u t o f college
gence o f new players and platforms, such as Google, Ama w ith a vision o f a b e tte r web developm ent environm ent. I
zon, eBay, and PayPal, which took advantage o f the oppor was very impressed w ith his early demos. He was a funny
tu n itie s and gaps in the market th a t the dotcom crash had and rather Likable kid, and he always wore red shirts. His
le ft behind. These companies would go on to become some name was S cott someone or another. I th in k he s till works
o f the most successful and in flu e n tia l in the history o f the a t M icrosoft today. <grin>
in te rn e t and to shape the future o f software development.
And before you ask, most o f the web applications we
wrote in those days were m ainly b u ilt fo r In te rn e t Explor
The Impact for CODE er, the de fa c to standard browser o f the tim e. Netscape
Luckily fo r us a t the CODE Group, the dotcom turbulences had faded in im portance as they Lost the "g rea t browser
were less severe than fo r oth er companies. Most o f the wars" against M icrosoft, and Firefox w asn't a th in g yet.
Other Important Tech I t may have seemed Like that to a Lot of us back then, but
.NET, and Visual Studio were super important technologies i t wasn't ju st a Microsoft world when i t came to operating
for all professional developers. Yes, Linux was also impor systems. Linux was always around and important in certain
tant, but when you worked with enterprise customers, scenarios. But there also was this niche operating system
Microsoft was where the lucrative projects were. (Some called Mac OS X. 20 years ago, I thought i t was neat. After
Linux enthusiasts may disagree, and I don't want to take all, i t had been born out of the very geeky-cool NeXT Step
anything away from them, but we weren't successful in operating system, developed by the NeXT company founded
making money with Linux in those days.) Microsoft's anti by Steve Jobs, and later integrated into Apple with Steve
trust lawsuit had come to an end, and although i t had an Job's return. I t didn't yet play a big role overall, and most
impact on how Microsoft had to operate for quite some people would never have considered buying a Mac. We used
time to come, i t did solidify Microsoft's position and the Macs in our magazine department, but generally, i t seemed
company represented a very solid and steady bet for most like something that wasn't very important to the business
enterprises around the world. When Microsoft pushed world, and i t was almost non-existent in our software de
out technology in the early 2000s, you could assume i t velopment considerations. (Another topic I'll have to re
was going to be not ju s t important and successful in the visit in the next articles in this series.)
Apple was also not a real player in mobile computing yet. Figure 2: The BlackBerry Figure 3: The first Xbox was released for the Christmas
Yes, Apple had the Newton years earlier, but that was 6000, released in 2003 2001 season.
ahead of its time and was soon discontinued. Palm Pilots
were also a thing of the past. But RIM's (Research-In-Mo
tion) BlackBerry was all the rage for mobile enthusiasts
(Figure 2). I t may have later gotten Hilary Clinton into
trouble as her email device of choice, but it was the state-
of-the-art mobile business solution for quite some time.
I t seems quaint today, but i t was considered unthinkable
that a device without a physical keyboard could be feasible
in business scenarios. This was an idea that Microsoft CEO
Steve Balmer held onto way too long, in the process killing
Microsoft's phone business. Today, most people don't even
remember that Microsoft had a strong position in that mar
ket segment, with Windows Mobile and Windows CE.
computers became a Lot more powerful, and our custom Let me first start by describing the code you've cloned here.
ers demanded th a t we build skyscrapers. You might have
heard of something called Moore's Law, which is the ob Code Structure
servation th a t the number of transistors on an integrated The code you've cloned is a simple nodejs project. I t uses
circuit w ill double every two years with a minimal rise in ExpressJS to serve a static website from the public folder,
cost. Yes, computers have become very powerful, but ju s t as can be seen in Figure 1.
due to basic physics and energy density issues, we've also
h it a wall in absolute computing power th a t we can pack To run it, just follow the instructions in readme.md. At a
within a single processor. As a result, the world started high level, it's a matter of running npm install, and hitting
Sahil Malik moving toward multiple cores, and multiple processors; F5 in VSCode. Additionally, you'll see that in index.js as seen
www.winsmarts.com even your phone— or maybe even your watch— now has in Listing 1, in addition to serving the public folder as a
@sahilmaLik multiple cores or multiple processors inside it. static website, I'm also exposing an API at the "/random"
URL. This API is quite simple; it waits for five seconds and
Sahil Malik is a Microsoft
When these multiple cores or multiple processes try to work returns a random number. I have a wait here to demonstrate
MVP, INETA speaker,
together, adding two processors doesn't always equal 2X the what effect blocking processes, such as this wait, can have
a .NET author, consultant,
performance. Sometimes it can even be less than IX because your browser's UI. The reason I've written this code in Node-
and trainer.
the competing processors might be working against each JS is because I could use identical code for the wait on both
Sahil loves interacting other. For sure, the benefit you get w ill be less than 2X be client and server, although this isn't a hard requirement.
with fellow geeks in real cause some overhead is spent on coordination. Now imagine
time. His talks and train if you have a 64-core processor, how would that look? And Let's also briefly examine the client side code. The in-
ings are full of humor and how would you write code for it? There w ill always be that dex.html file is quite simple. I t references jQuery to help
practical nuggets. one really smart guy on your team that understands the dif simplify some of the JavaScript I 'll write. I t has a but
ference between mutexes and semaphores, and that smart ton called btnRandom th a t calls a JavaScript. I t has a
His areas of expertise are guy w ill act Like the cow that gives one can of milk and tips div called "output" where the JavaScript can show mes
cross-platform Mobile app over two. His smarts w ill make rest of the team unproduc sages to communicate to the user. The idea is th a t I 'll call
development, Microsoft tive because, let's be honest, these concepts can be hard to a function th a t blocks for five seconds, and I'LL show a
anything, and security
understand, harder to write, and very hard to debug. "start" and the random number output message when the
and identity.
function starts and then when it's done.
Although it's no surprise th a t as we're building more
S ^ E complex software, our platforms and languages have also Additionally, I've placed a text area where users can type
ex- r^:? evolved to help us deal with this complexity, so the entire freely. The function takes five seconds to complete, so
team of mere mortals is productive. Languages have also what I'd like you to try is, within those five seconds, try
evolved to support more complex paradigms, and JavaScript to type in th a t text area. I f you can type in th a t text area
is no exception. while the function is executing, that's a non-blocking UI,
which is a good user interface. But i f the UI is frozen and
In this article, I'm going to explore a back-to-basics ap you cannot type in th a t textbox while your function runs,
proach by explaining asynchronous programming in Ja that's a bad user experience.
vaScript. Let's get started.
The user interface of my simple HTML file looks Like Fig
ure 2. The index.html file can be seen in Listing 2.
A Little Pretext
Before I get started, there's a little challenge I must deal
with. Demonstrating asynchronous concepts through text A Synchronous Call
and images as they appear in this article can be difficult. So Let's first start by writing a simple JavaScript function that
I'm going to describe the various concepts, but you should takes five seconds to execute. At the end of five seconds, it
also grab the associated code for this article at the follow simply returns a random number. This function is basically
ing URL: https://github.com/maliksahil/asyncjavascript. the same function you see in index.js called "waitForMil-
I recommend running the code side-by-side as you read this LiSeconds", except that for now, I'll ju st run it client side,
article as that w ill help cement the concepts. and the function itself w ill return a random number.
You'Ll notice that until the call completes and the random app.use(express.static( 1public1));
app.get("/random", (request, response) => {
number is shown in the output div, the page is essentially wai tForMiIT i Seconds(5000);
frozen. I t accepts no input from the user. In fact, the page is const random = {
dead: I t accepts or responds to no events. This is certainly a "random": Math .floor (Math. random() * 100)
bad user experience but may also lead to inexplicable bugs. };
response.send(random);
});
Callbacks app.listen(PORT, () =>
console.log('Server listening on port: ${PORT}'));
Now let's explore a technique in JavaScript called callbacks.
I f you remember what you first did, this line stands out: function waitForMilliSeconds(milliSeconds) {
var date = new Date();
var curDate = null;
randomNum = waitForMiHi Seconds(5000); do { curDate = new Date(); }
while (curDate - date < milliseconds);
This means th a t the returnvalue of waitForMilliSeconds is }
what gets populated in randomNum.
We've learned from other languages th a t you could pass in Listing 2: index.html
a function pointer to waitForMilliSeconds. Wouldn't i t be <html>
nice i f waitForMilliSeconds could call th a t function point
er when it's done with its five seconds of blocking work? <head>
<scri pt
src="https://code.jquery.com/jquery-3.7.1.min.j s"
To facilitate that, modify your waitForMilliSeconds function, i ntegri ty=".."
as shown below in the next snippet. The Login has been crossorigin="anonymous"></script>
</head>
trimmed for brevity and the only change is that instead of
sending back a return value, you're now accepting a param <body>
eter called callbackFunc. When you're done with your work, Press button to make async call:
<button type="button" id="btnRandom">Click</button>
you simply call this callback function and pass in the result. <br />
<div id="output"></div>
function waitForMiHiSeconds( <script src="scripts/l.sync.js "></script>
milliseconds, callbackFunc) { <br/>
var date = new Date(); <textarea rows="5" cols="40">Try typing here
while the long running call is running . .</textarea>
random = Math .floor (Math. random() * 100); </body>
callbackFunc(random); </html>
}
Accordingly, how you call this method also changes. This Listing 3: l.sync.js client side synchronous JS
can be seen below.
$("#btnRandom").on("click", function () {
$("#output").text("Start");
waitForMiHi Seconds(5000, (random) => { randomNum = waitForMiHi Seconds(5000);
$("#output").text(random); $("#output").text(randomNum);
}); });
function waitForMilliSeconds(miHiSeconds) {
As you can see, you're now calling waitForMilliSeconds var date = new Date();
with two input parameters. The firs t parameter instructs var curDate = null;
do { curDate = new Date(); }
the function to wait for five seconds and the second is an while (curDate - date < milliseconds);
anonymous function parameter. This function gets called return Math .floor (Math. random() * 100);
once waitForMilliSeconds is done and i t calls the callback- }
Func variable function.
Before you run this, what do you expect the behavior will Promise
be? Will it block the UI or not? Let's find out. Go ahead and JavaScript has yet another way of structuring your code,
run this. You'll notice that although the code seems to have which is Promises. You may have seen them when w rit
a different structure, the callback seemed to have no effect ing AJAX code, where your code can make an HTTP call
on the single-threaded nature of the code. The UI still blocks. to the server w ithout refreshing the whole page. This is
how complex apps such as Google Maps were born. Before
Bummer! Google Maps, navigating a map required you to refresh
the whole page. I t was a horrible user experience, until
Well, at Least you Learned a new concept here, and th a t someone showed us a better way. Technically speaking,
such callbacks have no effect on the single-threaded na Outlook for the web was leveraging this technique al
ture of execution. ready, but hey, this isn't a race.
Listing 5: Simple XHR request There are many ways to w rite AJAX code. I've referenced
$("#btnRandom").on("click", function () { jQuery and certainly jQuery has abstractions th a t help w rite
$("#output").text("Start"); AJAX code. The most basic way to call AJAX is by using XHR.
const xhr = new XMLHttpRequest();
xhr.addEventListener("loadend", () => { The way XHR works is th a t you in s ta n tia te a new instance
$("#output").text(xhr.responseText); o f XMLHttpRequest. You subscribe to the loadend event
}); and fire your HTTP request. Now whenever the call re
xhr.open("GET", "/random"); turns, the loadend event gets called and you get the re
sults. You can process accordingly w hether it's an error or
xhr.send();
$("#output").text("Sent xhr request"); success.
});
Let's s ta rt by in s ta n tia tin g the XMLHttpRequest.
The idea behind a JavaScript Promise is th a t the func You can see the fin a l code th a t puts a ll th is to g ethe r in
tio n doesn't return a value, b u t instead returns a Promise. Listing 5.
The Promise w ill e ith e r resolve (succeed) or reject (fa il).
When i t resolves, i t can send back a success o u tp u t. I f i t Remember from Listing 1, the server-side code is basical
fails, i t can send back an error. ly the same code you've been using except now instead o f
running on the clie n t, it's running on the server. I t waits
Your caller then uses standard paradigms around Promises five seconds and sends back a random number.
to handle success w ith a Then method.
Now go ahead and run th is by referencing th is script, press
Let's m odify the waitForM illiSeconds method to now re ing F5 to refresh the browser, and clicking the button.
turn a Pomise and resolve i t on success. You can see th is
method in Listing 4. Very in terestingly, now the UI doesn't block. How odd is
that?
This allows you to w rite calling code:
A lthough th is is great, w o u ld n 't i t be nice i f complex c li
waitForMiHi Seconds(5000).then( (random) => { ent-side code could be afforded the luxury o f being m u lti
$("#output").text(random); threaded? This XHR-based code feels so com plicated. My
}); example was simple, b u t im agine how th is could Look w ith
m u ltip le dependencies, in p u ts dependent on other XHR
Let's run th is code again and h it the click b u tto n . What calls succeeded, tim in g issues, etc. Ugh!
do you see?
Ah! Yet again, although the code functionally is accurate, i t Promises and XHR
s till blocks the UI thread. The code is s till single threaded. I t Let's s ta rt by cleaning th is code up a b it. You've already
responds to no in p u t while the function is running and sud seen Promises in action. Can you combine XHR and Prom
denly reacts to key strokes queued up in those five seconds. ises tog ethe r to help w rite code th a t's simpler? Sure! ALL
makeXhrCaH.().then((output) => {
Instantly Search
});
$("#output").text(output);
Terabytes
Now go ahead and run th is code. I t runs ju s t Like before
and i t doesn't block the UI thread. Is th is because you're
using a Promise or th a t you're using an XHR? Well, you
did use a Promise on a loop th a t was en tire ly on the c li
en t side and th a t did block the UI. This non-U I blocking
magic is b u ilt in to XHR. dtSearch's docum ent filters support:
• popular file types
Async Await • emails with multilevel attachments
Recently, JavaScript introduced support fo r async aw ait
keywords. The Promise code looks cleaner than pure XHR
• a wide variety of databases
code, b u t i t s t ill feels a b it inside out. Im agine i f you had • web data
three Promises you needed to w a it fo r and those inputs
go in to tw o more Promises, which fin a lly go in to another
AJAX call? Luckily, Promises do have concepts such as
resolveALl etc., which do help. They're an im provem ent
over pure XHR code. However, the code becomes severely
Over 25 search options including:
indented and you're stuck in a hell hole o f brace m atching • efficient multithreaded search
and keeping your code under 80 characters w idth.
• easy multicolor hit-highlighting
Async await helps you tackle th a t problem. Look a t the sync • forensics options like credit card search
code example from Listing 3. To convert th a t from sync to
async, all you have to do is add the async keyword in fron t
o f the function. In other words, change this line o f code:
SCOTT HANSELMAN SCOTT HUNTER MILAN KAUR DAN WAHLIN HEATHER DOWNING
Vice President, Vice President, Director Product Manager, Principal Cloud International Speaker &
Developer Community, Product Management Microsoft Developer Advocate, Developer Advocate
Microsoft for Azure Developer Microsoft
Experience, Microsoft
JEFF FRITZ JOHN PAPA MARKUS EGGER ZOIN ER TEJADA MICHELE LEROUX
Principal Program Partner G M - Cloud President and Chief CEO and Architect, BUSTAMANTE
Manager, Microsoft Advocacy, Microsoft Software Architect, Solliance President & Architect,
CODE Group Solliance
REGISTER TODAY!
w DEVintersection.com X@DEVintersection
Q [email protected]
JavaScript, Python, and alm ost any programming Lan Nested Objects
guage existing today. In th is article, you're going to Learn Each value after the name can be one of the various data
m ultiple methods o f creating and m anipulating JSON doc types shown in Table 1. Although this isn't a large List of data
uments in .NET 8. In a d d itio n , y o u 'll Learn how to serialize types, all data can be expressed w ith ju s t this set o f types.
and deserialize C# objects to and from JSON.
Look a t Figure 4 to see an example o f a JSON object th a t
has a value o f each o f the data types fo r each name. The
JSON Structure "name" property has a string value "John Sm ith" enclosed
As shown in Figure 1, a JSON o b je ct is made up o f a w ith in double quotes. The "age" property is a numeric w ith
Paul D. S h e riff collection o f nam e/value pairs. You may hear these also a value o f 31. The "ssn" property is empty as represented
http://www.pdsa.com expressed as key/value pairs, or, in C# terms, th is is a by the keyword null. The "address" property is another
property and a value. In C#, a JSON ob je ct is the equiva JSON object and is thus enclosed by curly braces. The
Paul has been working le n t o f an object, record, or a stru ct w ith property names, "phoneNumbers" property is a JSON array, w ith each value
in the IT industry since and the values you assign to those properties. JSON can o f the array another JSON object. As you see, JSON is very
1985. In that time, also be a collection o f one or more objects (Figure 2 flexible and can represent alm ost any type o f structure you
he has successfully
and Figure 3 ). In C#, th is would be the equivalent o f a can possibly need in your programming tasks.
assisted hundreds of
dictionary, hash table, keyed List, or associative array. A l
companies'architect
though I'm going to use C# in th is article, the constructs
software applications
m entioned are universal across a ll modern programming JSON Manipulation Classes
to solve their toughest
Languages. Because o f th is , any Language can m anipulate There are several classes w ithin a couple of namespaces in
business problems. Paul
has been a teacher and these JSON objects easily. .NET 8 th a t you use to work with JSON in your C# applications.
mentor through various The first namespace is System.Text.Json and the second
mediums such as video A JSON ob je ct begins w ith a Left brace and ends w ith namespace is System.TextJson.Nodes. You have most likely
courses, blogs, articles and a rig h t brace (see Figure 1). Each name is follow ed already used the JsonSerializer class to serialize C# objects to
speaking engagements by a colon and the nam e/value pairs are separated by JSON, or to deserialize a JSON string into a C# object. Howev
at user groups and a comma. Each name must be wrapped w ith in double er, there are other classes you can use to add nodes to a JSON
conferences around the quotes. A ll string values must be wrapped w ith in double object, set and retrieve values, and create new JSON objects.
world. Paul has multiple quotes.
courses in the www. The System.TextJson Namespace
pluralsight.com library A JSON array is an ordered collection o f values th a t be W ithin th is namespace are classes and structures to help
(https : // b it . Ly/3gvXgvj) gins w ith a le ft bracket and ends w ith a rig h t bracket. you m anipulate JSON documents in clu din g the JsonSe-
and on Udemy.com Each value w ith in the array is separated by a comma. The rializer class. Table 2 provides a description o f each o f
(https://bit.Ly/3W 0K8kX) values w ith in the array may be a single ite m , such as a the classes w ith in th is namespace. Each o f these classes
on topics ranging from C#, string or a number (Figure 2 ), or each value w ith in the is illu s tra te d th ro u g h o u t th is article. A ll the classes and
LINQ, JavaScript, Angular, array may be a JSON object (Figure 3 ). structures w ith in th is namespace are im m utable. This
MVC, WPF, XML, jQuery,
and Bootstrap. Contact
Paul at [email protected].
Figure 2: JSON arrays can have ju s t simple values as Figure 3: Each elem ent in a JSON array can be a JSON
th e ir elements. object.
Table 2: The System .TextJson namespace contains classes and structures fo r m anipulating and serializing JSON objects
Class Description
JsonObject This class represents a mutable (read/write) JSON document. This class is Like the JsonDocument class from the System.TextJson namespace.
JsonNode This class represents a mutable (read/write) node w ithin a JSON document. This class is like the JsonProperty class from the System.TextJson
namespace.
JsonValue This class represents a mutable (read/write) JSON value. This class is like the JsonELement class from the System.TextJson namespace.
JsonArray This class represents a mutable (read/write) JSON array.
Table 3: The System.TextJson.Nodes namespace contains classes fo r m anipulating in-m em ory JSON objects as a docum ent ob je ct model
means th a t once they've been in sta n tia te d w ith data, Below the Using statement, create a variable named jo th a t is
they cannot be m odified in any way. an instance of a JsonObject. The JsonObject provides the abil
ity to add, edit, and delete nodes w ithin the JSON document.
The System.TextJson.Nodes Namespace
The classes in th is namespace (Table 3) are for creating JsonObject jo = new();
and m anipulating in-memory JSON documents using a DOM.
These classes provide random access to JSON elements, al
low adding, editing, and deleting elements, and can con
vert dictionary and key value pairs in to JSON documents.
{
"name": "John Smith",
"age": 31
}
using System.TextJson.Nodes; Figure 4: Each elem ent in a JSON object can be another object, or an array.
Write out the JSON document using the ToString() meth using System.Text.Json.Nodes;
od on the JsonObject.
JsonObject jo = new() {
Console.Wri teLi ne(jo.ToString()); ["name"] = "John Smith",
["age"] = 1
The output from this statement is the JSON object shown };
earlier. Notice how the JSON is nicely formatted. I f you
wish to remove all of the carriage returns, Line feeds, and Console.WriteLine(jo.ToString());
whitespace between all the characters, change the call
from the ToString() method to the ToJsonString() method Create Nested JSON Objects
instead. You should then see the following JSON appear Not all JSON objects are simple name/value pairs. Some
in the console window. times you need one of the properties to be another JSON
object. The "address" property is another JSON object
{"name":"John Smith","age":31} th a t has its own set of name/value pairs, as shown in the
following snippet:
Use a New C# 12 Feature
In C# 12 (.NET 8) you can create the JsonObject using the {
following syntax. Note that the square brackets used in the "name": "John Smith",
code are a new C# 12 feature that allows you to initialize "age": "31",
the new JsonObject object without using the new keyword. "ssn": null,
"isActive": true,
JsonObject jo = "address": {
"street": "1 Main Street",
new KeyValuePair<string, "city": "Nashville",
JsonNode?>("name", "John Smith"), "stateProvince": "TN",
new KeyValuePair<string, "postalCode": "37011"
JsonNode?>("age", 31) }
]; }
Using a Dictionary Class To create the above JSON object, create a new instance
You can pass an instance of a Dictionary<string, Json- of a JsonObject and, using a Dictionary object, build the
Node?> to the constructor of the JsonObject to create structure you need, as shown in the following code snip
your JSON document. Replace the code in the Program.es pet:
file with the following:
using System.Text.Json.Nodes;
using System.Text.Json.Nodes;
JsonObject jo = new() {
Dictionary<string, JsonNode?> diet = new() { ["customer"] = "Acme",
["name"] = "John Smith", ["IsActive"] = true,
["age"] = 31 ["address"] = new JsonObjectQ {
}; ["street"] = "123 Main Street",
["city"] = "Walla Walla",
JsonObject jo = new(dict); ["stateProvince"] = "WA",
["postalCode"] = "99362",
Console.WriteLine(jo.ToString()); ["country"] = "USA"
}
Using a JsonValue Object };
The Add() method on the JsonObject class also allows you
to pass in the name and a JsonValue object. Pass in the Console.WriteLine(jo.ToString());
value to static method Create() on the JsonValue class to
create a new JsonValue object.
Parse JSON Strings into Objects
using System.Text.Json.Nodes; JSON documents are commonly stored as strings in a file or
in memory. Instead of attempting to read specific values in
JsonObject jo = new() { the JSON using File 10 or string parsing, you can parse the
{ "name", JsonValue.Create("John Smith") }, string into a JsonNode object. Once in this object, it's very
{ "age", JsonValue.Create(31) } easy to retrieve single values, or entire nodes.
Listing 2: Retrieve values from the JSON using the RootElement property / / Parse string into a JsonDocument object
using JsonSamples; using JsonDocument jd =
using System.Text.Json; JsonDocument.Parse(JsonStrings.PERS0N_ADDRES5);
/ / Parse string into a JsonDocument object / / Get a specific property from JSON
using JsonDocument jd =
JsonDocument.Parse(J sonStri ngs.PERSON); JsonElement je = jd.RootElement
.GetProperty("address") .GetProperty("city");
/ / Get a specific property from JSON
JsonElement je = / / Get the string value from the JsonElement
jd.RootElement!.GetProperty("name");
Console.Wri teLi ne($"Ci ty={j e! .GetStringO}");
/ / Get the numeric value
/ / from the JsonElement After parsing the string into the JsonDocument object, access
Console.Wri teLi ne( the RootElement property and call the GetProperty("address") to
$"Name={je! .GetStri ng()}" ) ; get to the "address" property, and then call GetProperty("city")
Console.Wri teLi ne(
$"Age={jd.RootElement! to get to the "city" property. Once you have this element in
.GetPropertyC'age")! .Getlnt32()}"); a JsonElement object, call the GetStringO method to retrieve
the value for the "city" property.
/ / Parse string into a JsonNode object Add, Edit, and Delete Nodes
JsonNode? jn = To add a new nam e/value pair to a JSON document, cre
JsonNode.Parse(J sonStrings.PERSON); ate a JsonObject object o u t o f the PERSON JSON string
constant and convert i t to a JsonObject using the AsOb-
/ / Get the age node je c t() method. Once you have a JsonObject, use the Add()
JsonNode? node = jn !["age"]; method to create a new nam e/value pair, in th is case
"hairC olor": "Brown".
W ith th is new JsonNode object, node, retrieve the value
as a JsonValue using the AsValue() method. W ith the using JsonSamples;
JsonValue object, you can report the path o f where th is using System.Text.Json.Nodes;
value came from , the type (strin g , number, Boolean,
etc.), and get the value its e lf as shown in the fo llo w in g / / Parse string into a JsonObject
code: JsonObject? jo = JsonNode.Parse(
JsonStri ngs.PERSON)?.AsObject();
/ / Get the value as a JsonValue
JsonValue value = node!.AsValueO; jo?.Add("hairColor" , JsonValue.Create("Brown"));
Console.WriteLine($"Path={value.GetPath()}");
Console.WriteLine($"Type={value.GetValueKind()}"); Console.WriteLine(jo?.ToString());
Console.WriteLine($"Age={value}");
Replace the code in the Program.es file w ith the code
A nother op tion is to retrieve the value using the listed above and run the application to see the fo llo w in g
GetValue<T>() method, as shown in the fo llo w in g code: displayed in the console window:
Console.WriteLi ne(jo?.ToString());
{
Replace the code in the Program.es file with the code "name": "John Smith",
listed above and run the application to see the following "age": 31
displayed in the console window. The "age": 31 name/ }.
value pair has been removed from the JSON document. {
"name": "Sally Jones",
{ "age": 33
"name": "John Smith", }
"ssn": null, ]
"isActive": true Array
}
Manipulate an Array
Like most arrays in .NET, you can easily add and remove
Working with Arrays elements within the array. Given the previous JsonArray
In addition to a simple object, JSON can contain arrays object declaration, you can insert a new entry into the
of strings, numbers, Booleans, and JSON objects. Instead array by adding the following code after the declaration.
of using the JsonObject to represent a JSON document, The Insert() method lets you specify where in the array
use the JsonArray class to represent a list of items. For you wish to add the new object. In this case, you are
example, to create an array of string values, replace the adding a new element into the first position of the array.
code in the Program.es file with the following:
ja.lnsert(0, new JsonObject() {
using System.Text.Json.Nodes; ["name"] = "Charlie Chaplin",
["age"] = "50"
JsonArray ja = [ "John", "Sally", "Charlie"]; });
Console.Wri teLi ne(j a.ToStri ng()); You can always create a new JsonObject first, initialize it
Console.WriteLine(ja.GetValueKind()); with some data, then add th a t new JsonObject to the Json
Array using the Add() method. The Add() method adds the
Run the application and you should see the following JsonObject to the end of the array.
code displayed in the console window. Notice th a t after
the JSON array is displayed, the type reported from the JsonObject jo = new() {
call to the GetValueKind() method is "Array". ["name"] = "Buster Keaton",
["age"] = 55
};
"John", j a.Add(jo);
"Sally",
"Charlie" Array elements may be removed by either a reference to
] the actual object, or by using an index number, as shown
Array in the following two lines of code:
using JsonSamples;
using System.Text.Json.Nodes; Listing 4: A sample runtime configuration file
{
// Parse string into a JsonNode object "runtimeoptions": {
JsonNode? jn = JsonNode.Parse( "tfm": "net8.0",
"framework": {
JsonStrings.PHONE_NUMBERS); "name": "Microsoft.NETCore.App",
"version": "8.0.0"
JsonArray? nodes = jn!.AsArrayO; }.
foreach (JsonNode? node in nodes) { "configProperties": {
"System.Runtime.. false
Console.Wri teLi ne($"Type={node!["type" ]}, }
Phone Number={node!["number"]}"); }
} }
using System.Text.Json.Nodes;
Writing to a File
string connectstring = string.Empty; I f you're running a WPF application, or a console application,
string fileName = "appsettings.json"; it's perfectly acceptable to write data back to the appset
i f (File.Exists(fileName)) { tings.json file. Of course, you wouldn't want to do this when
// Read settings from file running an ASP.NET web application. The code shown in List
JsonNode? jd = JsonNode.Parse( ing 8 reads in the appsettings.json file, adds a new name/
File.ReadAllText(fileName)); value pair, then writes the new JSON back to the appsettings.
// Extract the default connection string json file. Type the code in Listing 8 into the Program.es file
connectstring = jd !["Connectionstrings"] and run the application to produce the following results:
! ["Defaultconnection"]?
.GetValue<string>() ?? string.Empty;
} {
"Connectionstrings": {
Console.WriteLine(connectString); "Defaultconnection": "Servers..;"
• Microsoft. Extensions.Configuration
• Microsoft. Extensions.Configuration. Json Listing 9: Use the Configuration Builder class to read in a JSON file
After adding these two packages to your project, you can using Microsoft.Extensions.Configuration;
write the code shown in Listing 9. In this code, you pass string? value = string.Empty;
in the runtime configuration file name (see Listing 4) string fileName =
to the AddJsonFile() method on the Configuration Builder. $"{AppDomai n.CurrentDomain.FriendlyName}
.runtimeconfig.json";
The Build() method is called to create the configuration
builder object, which reads the JSON file into memory IConfiguration config =
and converts the text into a JSON document. Use the new ConfigurationBuiIder()
.AddJsonFile(fileName)
GetSection() method to retrieve a specific section within .BuildO;
the JSON file. In this case, you're asking for the runtime-
Options section. From the section variable, you can now IConfigurationSection section =
config.GetSection("runtimeoptions");
retrieve the framework version number. Type in the code value = section["framework:version"]
in Listing 9 into the Program.es file, run the applica ?? string.Empty;
tion, and you should see the version number appear in
Console.Wri teLi ne(value);
the console window.
IConfigurationSection section =
Bind Settings to a Class config.GetSection("Connectionstrings");
Instead of reading values one at a time from a configura connectstring =
section["Defaultconnection"]
tion file, you can bind a section within a configuration ?? string.Empty;
file to a class with ju s t one line of code. Create a class
named AppSettings and add a property th a t maps to each Console.WriteLine(connectstring);
name in the configuration file. In the following code,
there's a sole property named Application Name that
maps to the "ApplicationName" property in the appset To perform the binding operation, add the package Micro-
tings.json file shown in Listing 6. soft.Extensions.Configuration.Binder to your project
using the NuGet Package Manager. Add the following code
namespace JsonSamples; to the Program.es file and run the application to see the
application name displayed in the console window:
public class AppSettings
{ using JsonSamples;
public string ApplicationName { get; set; } using Microsoft.Extensions.Configuration;
= string.Empty;
} AppSettings entity = new();
Person entity = new() { This code uses the Serialize() method of the JsonSerializer
Name = "John Smith",
Age = 31, class from the System.Text.Json namespace. Pass in the in
SSN = null, stance o f your C# object to the Serialize() method and a string
IsActive = true of JSON is returned. Run the application and you should see
};
the following string of JSON appear in your console window:
JsonSerializerOptions options = new() {
PropertyNamingPolicy = {"Name":"John Smith","Age":31,
JsonNamingPolicy.CamelCase,
Writelndented = true "SSN"m ull,"IsActive":true}
};
Notice th a t there's no in d e n ta tio n or spaces between the
Console.Wri teLi ne(
JsonSerializer.Serialize(entity, options)); values. Also notice th a t the names are the exact same
case as your C# class property names. JSON usually uses
camel case fo r names (firs t le tte r is Lower-case), whereas
C# uses Pascal case (firs t Letter is upper-case).
Listing 12: Add JSON a ttrib u te s to your C# class properties to con trol serialization
[Jsonlgnore]
public DateTime? CreateDate { get; set; }
[Jsonlgnore(Condition = "name": "John Smith",
JsonlgnoreCondition.WhenWritingNull)] "age": 31,
public DateTime? ModifiedDate { get; set; }
"ssn": null,
public override string ToStringO "IsActive": true
{
return $"{Name}, Age={Age},
SSN={SSN}, IsActive={IsActive}";
} Go back to the Program.es file and change the Proper
} tyNamingPolicy property to JsonNamingPolicy.Snake-
using JsonSamples;
using System.Text.Json;
AppSettingsNested entity = new() { JsonSerializerOptions options = new() {
ApplicationName = "JSON Samples", PropertyNamingRolicy = JsonNamingPolicy.CamelCase,
JWTSettings = new() { Writelndented = true
Key = "ALongKeyForASymmetricAlgorithm", };
Issuer = "JsonSamplesAPI",
Audience = "PDSCJsonSamples", Console.Wri teLi ne(
MinutesToExpi rati on = 60 JsonSerializer.Serialize(entity, options));
public override string ToStringO er class. This class works w ith the serializer and instead
{ o f e m ittin g the numeric value o f enum eration properties,
return $"{Name}, Type={PersonType}"; i t em its the string representation o f the enum eration.
}
} JsonSerializerOptions options = new() {
PropertyNamingPolicy =
Open the Program.es file and w rite the code shown in the JsonNamingPolicy.CamelCase,
code snippet below: Writelndented = true,
Converters =
using JsonSamples; {
using System.Text.Json; new JsonStringEnumConverter()
}
PersonWithEnum entity = new() { };
Name = "John Smith",
PersonType = PersonTypeEnum.Supervisor A fte r adding the JsonStringEnumConverter object, run
}; the application and the fo llo w in g should now display in
the console window:
JsonSerializerOptions options = new() {
PropertyNamingPolicy = JsonNamingPolicy.CamelCase, {
Writelndented = true "name": "John Smith",
}; "personType": "Supervisor"
}
Console.Wri teLi ne(
JsonSerializer.Serialize(entity, options)); Serialize a Nested Object
Often you have a property in a class th a t is its e lf another
When you run the ap plication, the fo llo w in g o u tp u t is class. Don't worry, the JSON serialization process handles
displayed in the console window. this situation ju s t fine. To illustrate, create a class called
JwtSettings, as shown in Listing 14. Next, create a class
{ named AppSettingsNested th a t has tw o properties: Appli-
"name": "John Smith", cationName and JWTSettings. The data type for the JWT-
"personType": 3 Settings property is the JwtSettings class you ju s t created.
}
namespace JsonSamples;
Notice th a t the personType property has a value o f 3,
which equates to the Supervisor enum eration value. Go public class AppSettingsNested
back to the Program.es file and add the fo llo w in g using {
statem ent a t the to p o f the file : public string ApplicationName
{ get; set; } = string.Empty;
using System.Text.Json.Serialization;
public JwtSettings JWTSettings
Set the Converters property in the JsonSerializerOptions { get; set; } = new();
ob je ct to use an instance o f the JsonStringEnumConvert- }
{
"name": "John Smith", Deserialize JSON into a C# Object
"personType": 3 Now th a t you've seen how to serialize a C# object in to
}. JSON, let's Look at reversing the process. To illustrate, cre
{ ate a JSON string w ith the JSON property name th a t exactly
"name": "Sally Jones", matches the C# property name in the class you wish to dese
"personType": 1 rialize this JSON in to . You use the JsonSerializer class (List-
ing 17) Like you did for serializing, but call the Deserialize() case. I f you fo rg e t to use the options and the property
method passing in the data type you wish to deserialize the names have d iffe re n t casing, then no data is mapped from
JSON string in to and the string itself. Type the code in List the JSON to the C# object, so an em pty ob je ct is returned
ing 17 in to the Program.es file and run the application to from the Deserialize() method.
see the follow ing results displayed in the console window:
Deserialize Using the JsonNode O bject
John Smith, Age=31, SSN=, IsActive=True A nother op tion fo r deserializing JSON in to a C# ob je ct is
to use e ith e r the JsonNode or the JsonDocument classes.
Use S erialization O ptions The code shown in Listing 19 uses the JsonNode object
Just like you did when serializing, i f the case o f the JSON to illu s tra te . The JsonDocument class looks very sim ilar to
property names doesn't match the C# property names, you th a t o f the JsonNode. Type th is code in to the Program,
may set the PropertyNameCaselnsensitive property to cs file and run the application to get the same o u tp u t as
true in the options and pass those options to the Dese- you saw in the Last example.
ria lize () method, as shown in Listing 18. Notice th a t in
th is lis tin g the JSON property names s ta rt w ith Lower- Deserializing E num eration Values
I f you know th a t the JSON object is going to have the
string representation o f a C# enum eration, set the Con
verters property to a new instance o f the JsonString-
EnumConverter class in the JsonSerializerOptions object,
ADVERTISERS INDEX as shown in Listing 20. I f you forg et to include the Con
verters property on the JsonSerializerOptions, a Json Ex
ception is thro w n. Type the code shown in Listing 20
Advertisers Index in to the Program.es file and run the application to see
the fo llo w in g o u tp u t appear in the console window:
CODE Consulting--AI Services
www.codemag.com/ai-services 2 John Smith, Type=Supervisor
Devlntersection {
"name": "Sally Jones",
www.devintersection.com 15
Advertising Sales: "age": 39,
Tammy Ferguson LEAD Technologies "ssn": "555-55-5555",
832-717-4445 ext 26
www.leadtools.com 5 "isActive": true
[email protected]
}
Convert a JSON A rray in a File to a List o f Person Objects Listing 21: Read a JSON file and convert the JSON object in the file in to a C# object
Right mouse-click on the JsonSampleFiles fold er and add using JsonSamples;
a new file named persons.json. Place the fo llo w in g JSON using System.Text.Json;
array in to th is file :
string fileName =
$"{AppDomain.CurrentDomain.BaseDi rectory}
JsonSampleFi lesWperson. json";
{
"name": "John Smith", using FileStream stream = File.OpenRead(fileName);
"age": 31,
JsonSerializerOptions options = new() {
"ssn": null,
PropertyNameCaselnsensitive = true,
"isActive": true };
}.
{ // Deserialize JSON string into Person
Person? entity = JsonSerializer
"name": "Sally Jones",
.Deserialize<Person>(stream, options);
"age": 39,
"ssn": "555-55-5555", Console.WriteLine(entity);
"isActive": true
}
Listing 22: Read an array o f JSON objects from a file and convert to a List o f person objects
Open the Program.es file and type in the code shown in using JsonSamples;
using System.Text.Json;
Listing 22. This code is almost the same as the code you
wrote to deserialize a single person object; the only d iffe r string fileName =
ence is th a t you pass the data type List<Person> to the De $"{AppDomain.CurrentDomain.BaseDi rectory}
serializeO method. Once you have the collection o f Person JsonSampleFi lesWpersons. json";
objects, iterate over the collection and display each person
using FileStream stream = File.OpenRead(fileName);
on the console window. Run the application and you should
see the follow ing o u tp u t displayed in the console window: JsonSerializerOptions options = new() {
PropertyNameCaselnsensitive = true,
John Smith, Age=31, };
SSN=, IsActive=True // Deserialize JSON string into List<Person>
Sally Jones, Age=39, List<Person>? lis t = JsonSerializer
5SN=555-55-5555, IsActive=True .Deserial1ze<List<Person»(stream, options);
i f (lis t != null) {
Get M a x im u m Age from List o f Person Objects foreach (var item in lis t) {
A fte r reading in a lis t o f objects, you may now use LINQ Console.WriteLine(item);
operations or any Enumerable methods such as Min, Max, }
Sum, and Average on th a t List. In the code shown in List }
ing 23, the Max() method is applied to the List and the
maximum value found in the Age property is displayed on
the console window. When you run th is ap plication, the able interface, so you need to prefix them w ith the Using
value reported back should be th irty -n in e (39). statem ent. You must s ta rt each JSON docum ent by calling
the W riteS tartO bject() or the W riteStartArray() method.
You then call the appropriate method to w rite a string , a
Using the Utf8JsonWriter Class number, a Boolean, a null, or a comment. Finally, call the
The U tf8JsonW riter class is a high-perform ance, forward- W riteEndObject() or the W riteEndArray() method to close
only, non-cached method o f w ritin g JSON documents. the JSON document. Type the code shown in Listing 24
Just Like w ith serialization, you can co n tro l the o u tp u t o f in to the Program.es file and run the application to display
the JSON to include w h ite space, and in d e n ta tio n . List the o u tp u t shown below in the console window:
ing 24 shows how to w rite a single JSON ob je ct in to a
Memorystream object. Note th a t both the Memorystream {
and the U tf8JsonW riter objects im plem ent the IDispos- "name": "John Smith",
using JsonSamples;
using System.Text.Json;
/ / Deserialize JSON string
string fileName = List<Person>? lis t = JsonSerializer
$"{AppDomain.CurrentDomai n.BaseDi rectory} .Deserialize<List<Person>>(stream, options);
JsonSampleFi lesWpersons. json";
/ / Calculate maximum age
using FileStream stream = File.OpenRead(fileName); int maxAge = lis t? .Max(row => row.Age) ?? 0;
Listing 24: The Utf8JsonW nter object is a forward-only cursor fo r e m ittin g JSON quickly
Listing 25: The Utf8JsonW riter o b je ct can w rite arrays as w ell as single objects
here's a lin k fo r those issues: https://bit.ly/E FC ore8Fea- have a firs t name property and a Last name property in a
tures. The lis t o f issues fo r the fixes can be perused at Customer class.
https://bit.Ly/EFC ore8Fixes.
public class Customer
I f you've follow ed my tech wanderings over the years, {
i t may be no surprise th a t my A#1 favo rite new feature public int Customerld { get; set; }
is the ComplexProperty mapping, an alternative to using public string FirstName { get; set; }
Owned Entities to map complex types and value objects. public string LastName { get; set; }
The new ComplexProperty mapping provides a far superior public DateOnly FirstPurchase { get; set; }
way to map complex types (and therefore, value objects) } Julie Lerman
than the Owned E ntity mapping we've been using since @julielerman
the beginning o f EF Core. To be clear, there are s till some Instead o f using tw o string types fo r every class th a t needs
th edatafarm .com/co nta ct
scenarios th a t are n o t y e t supported, so you may end up a person's name, you can create a new class th a t only has
those tw o strings. Julie Lerman is a Microsoft
using a m ix o f the tw o mappings u n til ComplexProperty is
Regional director, Docker
complete. It's the team's in te n tio n fo r th is to eventually
public class Customer Captain, and a long-time
replace Owned Entities in th e ir entirety. ComplexProperty
{ Microsoft MVP who now
is a big deal and i t was a big deal fo r the team to execute.
public int Customerld { get; set; } counts her years as a coder
It's a t the to p o f th e ir "w hat's new" lists as w ell.
public PersonName Name { get; set; } in decades. She makes
public DateOnly FirstPurchase { get; set; } her living as a coach and
A lthough the OwnsOne and OwnsMany mappings have consultant to software
fu lfille d the basic need to map classes th a t are used as
}
public class PersonName teams around the world.
properties o f e n titie s, the work th a t they were doing un You can find Julie present
{
der the covers was com plicated and led to numerous side ing on Entity Framework,
public string FirstName { get; set; }
effects. The team had tweaked the in ne r Logic a number Domain-Driven Design and
public string LastName { get; set; }
o f tim es across versions, creating breaking changes along other topics at user groups
}
the way, b u t never really solved the problem properly. and conferences around
They have been contem plating a replacement fo r some the world. Julie blogs at
PersonName is a complex type and can be used as a prop
tim e and have fin a lly pulled i t off. thedatafarm.com/blog, is
erty o f any other class, such as th is Ship Label class, which
the author of the highly
is obviously missing an address b u t th a t's only to keep
There are some caveats, however, which are a few capabili acclaimed "Programming
th is explanation simple.
ties th a t didn't make i t in to EF Core 8 bu t w ill be ready for Entity Framework" books,
EF Core 9. In those cases, we ju s t continue using the owned and many popular videos
public class ShipLabel
on Pluralsight.com.
e n tity mappings. I 'll explain the caveats after I allow you to {
feast your eyes on the new ComplexProperty mapping. public int Id { get; set; }
pubic DateOnly Printed {get; set;}
public PersonName Name { get; set; }
TLDR Complex Types and Value Objects }
Let's be sure we're a ll on the same page. A complex type
is a class th a t doesn't have any id e n tity and is used as The most im p o rta n t a ttrib u te o f PersonName is th a t i t
a property o f another class. An easy example is i f you has no id e n tity .
Mapped as ComplexProperty
Listing 2: Retrieving a Customer and Using its Name for a new Label Customer
var storedCustomer = ctx.Customers.First(); Customerld (inti J Name (PersonName) ||Hm
var label = new ShipLabel
{
Name = storedCustomer.Name, I 2 ' 1T
" ' ’ ■1
};
var label? = new ShipLabel
{ H ComplexType (Customer N.ime/'PrrsonName)
Name = storedCustomer.Name,
};
ctx.AddRange(label, label?); Figure 1: Data Model with Person mapped as an Owned
ctx.SaveChanges(); Entity vs. a Complex Property
With the owned entity mapping, the Customer's Name and A Quick Records Overview
the Name of only one of the ShipLabels (remember, EF Records have a number of formats. I spent a lo t of time
Core moved it, not copied it), are tracked separately and understanding the various ways to express a record to
it's a b it convoluted. choose the correct flavor. The documentation was very
helpful (https://learn.m icrosoft.com /en-us/dotnet/
Listing 3 shows the DebugView when PersonName is csharp/language-reference/builtin-types/record), but it
mapped as a ComplexProperty: This time, I'm sharing the s till took a few read throughs for me. I have encapsu
LongView with more details because it's so easy to read. lated some of the important details in Table 1 for a quick
The details look ju s t as you would expect. And EF Core is reference.
doing a lo t less work to manage the PersonName data.
To begin with, a record, by default, is a reference type.
It's much simpler and the side effects of the fake entities But a record struct is a value type— the correct choice for
ju s t disappear. a value object. There are more decisions to make.
Otherwise, you'll need to go back to mapping with OwnsOne. But— and this is a big but— on its own, a record struct
is not, I repeat, not, immutable. Therefore, i t fails the
What about records instead of a class? I recall firs t seeing requirement of a value object. Luckily, C#12 added the
the exploration th a t the C# team was doing on records capability to make a record struct read only.
at an MVP summit quite a few years ago. Because of how
they simplified creating value objects, I was definitely public readonly record struct PersonName (
eager to see them come into the language. Record types string FirstName, string LastName);
internalize equality comparison so you don't need to
override the Equals or GetHasCode methods every single That's a very succinctly expressed and simple value object.
time.
I f you do need additional logic, you can express the re
However, records did not play very well with owned enti cord more like a class with properties and other logic ex
ties and again, there were side effects to worry about. plicitly defined, as I'm doing here, using in it accessors
Therefore, I never used records u ntil EF Core 8 brought us to ensure th a t it's s till immutable. This is an example of
the ComplexProperty mapping and I had a b it of catching a read-only record struct w ithout positional properties.
public string FullName => When Name is null, the Name_FirstName and Name_Last-
$"{FirstName} {LastName}"; Name database fields are both null as well. When I re
} trieve the customer, EF Core returns a Customer with a
null Name property.
There's an interesting capability of records th a t you
should consider, which is th a t it's possible to create a new At some point, ComplexProperty w ill have the same be
instance of a record with new values. This feature uses a havior. But currently (in EF Core 8), specifying Name as a
with expression to replace property values. nullable type results in a runtime exception. The exception
you get is dependent on how the value object is defined.
For example, I might have instantiated a PersonName using:
I f the value object is a class, you get a message about the
var jazzgreat=new PersonName("Ella", fact that i t can't be optional when EF Core is attempting
"Fi tzgeralde"); to build the data model based on the DbContext mappings.
Then I discover the typo of the "e" at the end of her System.InvalidOperationException: 'Configuring the complex
name. Of course, with only two properties, I could eas property 'Customer.Name' as optional is not supported,
ily create a new instance from scratch. But i f you have call ' IsRequired()'. See https://github.com/dotnet/efcore/
a lot of properties, you could use the with expression issues/31376 for more information.'
syntax:
Making i t required ju s t so EF Core is happy is not a pleas
jazzgreat=jazzgreat with ing solution. I t should only be required i f your domain
{LastName = "Fitzgerald"}; invariants specify th a t Name should be required. I f it's re
quired, you can use ComplexProperty. I f not, you're stuck
There are a lot of other nuances of records th a t you can with OwnsOne.
learn about in the docs at https://learn.m icrosoft.com /
en-us/dotnet/csharp/language-reference/builtin-types/ I f PersonName is a record struct (with or w ithout posi
record. tional properties), you'll trigger a different exception. EF
Core configures the database fields from the value ob
Because I found i t confusing to sort out all of the behav je c t properties (Customer_FirstName, and Customer_Last-
iors of the various flavors of record types, I've listed the Name) as non-nullable fields. At runtime, the database
critical aspects of each (as well as class for comparison) w ill throw an exception saying th a t i t can't insert a null
in Table 1. value into a non-nullable column.
the overhead o f m aintaining underlying infrastructure. SDK to o l. The to o l scans ASP.NET and ASP.NET Core solu
But fo r apps th a t are already deployed on-premises, i t tion s (and, optionally, th e ir binary dependencies) fo r a
can be d iffic u lt to know how to get started re-p la tform wide variety o f p o te n tia l issues th a t need to be addressed
ing to one o f these environm ents. Even though .NET ap prior to running in Azure PaaS environm ents.
plications can often by deployed to Azure App Service
w ith m inim al changes, there are usually some changes Although th is article focuses on the experience o f using
required and discovering w h at those are can take some Azure Migrate application and code assessment fo r .NET,
tr ia l and error. there is also a Java version o f the to o l available. To Learn
more about the Java experience, please v is it h ttp s ://le a rn .
Mike Rousos This article introduces a new feature: Azure Migrate ap m icrosoft.com /azure/developer/java/m igration/appcat.
[email protected] p lica tion and code assessment. This new feature allows
analyzing the source code, con figu ratio n, and binaries
Mike Rousos is a Principal o f an application to discover upfront w hat changes w ill
Relationship to Other Azure Migrate
Software Engineer on the be needed fo r the app to work in Azure. Azure Migrate Features
.NET Customer Engage
application and code assessment make i t easy to plan Using Azure Migrate to prepare fo r a m igration to the
ment Team. A member of
re-platform ing to Azure and high lig hts w hat work w ill be cloud is n 't new, o f course. Azure Migrate has helped users
the .NET team since 2004,
needed along the way. Azure Migrate application and code discover and assess on-premises infrastructure fo r some
he has worked on a wide
assessment is a developer-focused experience available as tim e. Azure Migrate also includes the Data M igration As
variety of feature areas and
both a Visual Studio extension and a command Line .NET sista n t to help users assess SQL Server databases fo r m i-
contributed content to the
.NET team blog, .NET Conf
sessions, Channel 9 videos,
*■1
and .NET development e-
books Like "NET Microser
0
vices: Architecture for
Containerized .NET Appli Visual Studio | M a rke tp la ce Mika Rouwt (mikatou^rracrtnofLcom) Sign out
Figure 1: Azure Migrate application and code assessment extension download page
38 Preparing for Azure with Azure Migrate Application and Code Assessment codemag.com
gration to Azure SQL DB, Azure SQL Managed Instance,
Search Solution Explorer (Ctrl +;)
or SQL Server on an Azure VM. Azure Migrate can even
a S Solution ‘eShop Leg acyM VC (3 of 3 projects)
discover web apps hosted on-premises and ( if no blocking
issues are detected) autom ate m igrating them to Azure r> ft eShopLegacy.Common
w ith its App Service M igration Assistant to o l. > fi eShopLegacy.Utilities
— U d U y ivi v
Up u n til now, though, Azure Migrate hasn't had the a b ility tew Build
lected Services
to look a t the source code o f the applications i t detected. Rebuild lerties
The App Service M igration Assistant to o l can provide in
Clean fences
s ig h t in to w hether there are likely to be issues m igrating
View ► _Data
to Azure based on IIS con figu ratio n, b u t i t doesn't have
v is ib ility in to what's happening inside the code o f the Analyze and Code Cleanup ► .Start
ap plication. The Azure Migrate application and code as & Publish-. ent
sessment feature fills th is gap. The Visual Studio exten rollers
sion or command line to o l can assess your source code o f Upgrade
5
your solution and id e n tify p o te n tia lly problem atic APIs 1 . Re-platfcrm to Azure
jes
and code patterns. This assessment is a useful follow -up ** Configure Application Insights...
els
to the discovery by oth er Azure Migrate features. I t is
recommended to use Azure Migrate's existing application Overview ifrastructure
i r r n i m tV io iA /M o r io le r e
discovery features to gain in s ig h t in to the com plete set
o f applications to be m igrated. Then, a fte r the applica Figure 2: The Re-platform to Azure command opens the new to o l UI.
tion s have been reviewed and prio ritize d , Azure Migrate
application and code assessment can be used by devel
opers to dive deeply in to the applications th a t w ill be AppCAT: Hom e -o X
✓ •] eShopLegacyMVC
Note th a t the Azure Migrate application and code assess
m ent Visual Studio extension requires Visual Studio 2022.
I f you do n 't have Visual Studio 2022, the free commu Figure 3: Selecting projects to be analyzed fo r Azure m igration readiness
n ity e d itio n is available a t h ttp s ://v is u a ls tu d io .m ic ro s o ft.
com /downloads.
also binary dependencies, as shown in Figure 4. Choos
in g to analyze source code w ill Look a t th e source code
Analyzing a Solution o f th e selected pro je cts— C# or Visual Basic code file s,
To begin analyzing a solutio n, open the solution in Visual p ro je c t file s , con fig file s , and s ta tic co n te n t. This op
Studio and rig h t-c lic k on i t in the solution explorer. W ith tio n should ty p ic a lly be checked. I f you also check the
the Azure Migrate application and code assessment exten Binary dependencies o p tio n , th e to o l also analyzes
sion installed, there w ill be a new command available: binaries th a t th e projects depend on. This includes re f
Re-platform to Azure, as shown in Figure 2. Choosing erences to Loose DLLs, references to assemblies (o th e r
th is op tion opens a new user interface fo r managing tha n .NET Framework com ponents) in th e g lo b a l assem
Azure Migrate application and code assessment reports. bly cache, or referenced NuGet packages. Choosing to
analyze binaries produces th e m ost com prehensive set
A fte r clicking New Report, you w ill be able to choose o f issues th e a p p lica tio n may run in to w h ile m ig ra tin g ,
which projects in the solution you wish to assess, as b u t i t also includes more issues tha n analyzing on ly
shown in Figure 3. Note th a t the Azure Migrate applica source code and may include issues th a t you're n o t able
tio n and code assessment feature autom atically analyzes to fix d ire c tly (because th e y e xist in com ponents you
dependencies o f selected projects, so you only need to d o n 't have source code fo r) or th a t a re n't relevant i f
choose to p -le v e l projects you're interested in . A ll recur th e y e xist in code paths n o t used from you r a p p lic a tio n .
sive p ro je c t-to -p ro je c t dependencies o f the selected pro j A useful strategy is to begin on ly by analyzing source
ects w ill be included autom atically. code and Later consider producing another re p o rt w ith
binary analysis enabled i f there are binary dependencies
A fte r c lickin g next, the fo llo w in g UI w ill allow you to whose Azure-readiness you're unsure o f and would like
choose w hether to scan o n ly source code and settin gs or to learn more about. Because issues in binary dependen-
codemag.com Preparing for Azure with Azure Migrate Application and Code Assessment 39
cies can't be fixed directly by updating source code, they The report's dashboard includes the to ta l number of proj
are typically addressed by finding updated versions of ects scanned, the number of incidents discovered, and
the binaries, working with partners who can change the graphics showing the incidents by category and severity.
source code, or finding alternative solutions th a t work The report include both a number of issues th a t are the
better in Azure. types of problems detected and a number of incidents
th a t are the individual occurrences of the issues.
Once you click the Analyze button, the extension analyzes
the selected projects for any potential issues re-platform Azure Migrate application and code assessment issues are
ing to Azure. This analysis w ill take anywhere from a few each assigned one of four severities:
seconds to a few minutes, depending on the size of the
projects. When the analysis is complete, you'll be shown 1. Mandatory: Mandatory issues are those th a t likely
a report summarizing the results. (See Figure 5.) This re need to be addressed before the application w ill work
port can be saved to disk and returned to Later using the in Azure. An example of a mandatory issue is using
save icon (or common shortcuts Like Ctrl+S). Windows authentication to authenticate web app us
ers. Because th a t authentication mechanism depends
on the on-premises Active Directory environment, i t
w ill Likely need to be updated in the cloud to use
Azure AD or some other authentication alternative.
2. Optional: Optional issues are opportunities to im
prove the application when it's running in Azure, but
they aren't blocking issues. As an example, storing
app settings or secrets in a web.config file is consid
ered an optional issue. That pattern w ill continue to
work when deployed in Azure, ju st like on-premises,
so no changes are required. Apps that are hosted in
Azure can take advantage of services like Azure App
Configuration and Azure Key Vault to store settings
in ways that are easier to share and update and that
are more secure. So, there's an optional issue to be
gin taking advantage of these services as part of the
Azure re-platform.
3. Potential: Potential issues represent situations where
there might need to be a change made for the app to
work in Azure, but it's also possible that no change is
needed, depending on the details of the scenario. This
Figure 4: Choosing whether to analyze source code or binaries severity is common and requires an engineer to review
Figure 5: The Azure Migrate application and code assessment report dashboard
40 Preparing for Azure with Azure Migrate Application and Code Assessment codemag.com
the incidents. As an example, connecting to a SQL viewing incidents for a particular project, you can choose
Server database is a potential issue because whether to view all incidents for the project or to view incidents
a change is needed depends on whether the database per component (a single source file or binary dependency
that's used is accessible from Azure. I f the database is considered a component).
is already hosted in Azure or is accessible from Azure
(via Express Route, for example), no changes are need In incident detail views, there w ill be a state drop-down
ed. On the other hand, if the database used exists box indicating whether each incident is Active, Resolved,
on-premises without a way for the app to connect to or Not Applicable (N/A). ALL incidents begin as Active
i t once it's running in Azure, thought w ill need to be and you can change the state as you investigate. Reports
given to how this dependency w ill work after the app can be saved (using the save icon in the top right of the
is re-platformed. Perhaps the database w ill need to be report) and the state w ill be persisted so th a t you can
migrated alongside the app or perhaps a solution like return to the same report in the future and continue to
Express Route or Hybrid Connections w ill be needed to review remaining issues and further update the state. As
make the database accessible. you review the incidents in the report, mark incidents
4. Information: Information issues are useful pieces th a t don't need to be addressed in your solution as not
of information for the developer to know but don't applicable and those th a t you've fixed as resolved. The
require any action. As of the time of this writing, incident detail pages also give descriptions of why the
there aren't any information issues in Azure Migrate incidents were identified, why they matter, and how you
application and code assessment for .NET (although can address them. These detail views, shown in Figure 6,
there are a couple in the Java version of the tool). include Links to documentation and Links to the locations
in source code where the issues were detected.
In addition to severity, each incident in the report in
cludes a story point number. This is a unitless number In addition to working with reports in the Visual Stu
representing the relative effort estimated to address the dio IDE, it's possible to export the reports to share with
incident (if, in fact, i t needs to be addressed). These others. The Export button in the top right of the report
shouldn't be used to estimate the precise amount of work interface allows you to export the report in three differ
in terms of hours or days but can be used as a rough ent formats:
estimate for comparing two projects. I f one solution has
500 story points worth of issues and another has 200 • Export as HTML produces the most readable report for
story points worth of issues, it's probably true th a t the sharing with others. The HTML report, shown in Figure
solution with fewer story points of issues w ill be simpler 7, has all the same dashboards and views as the Visual
and easier to re-platform. Studio UI and includes snapshots of the Latest state of
all incidents. This report is best for sharing with others
From the in itia l dashboard, you can navigate to views dis for viewing issues and investigation progress.
playing aggregate issues (all incidents organized by issue • Export as CSV produces a report with the same in
type) or projects (incidents organized by project). When formation but in a spreadsheet format. As seen in
• eShopLegaCyMVC.CSproj (C\xc\mpou»os\UpgradeSaznp‘<‘V>et4??\eShopiegaQMVC)
stuet
COMPONENT STATE K IN D IS S U E S ® IN C ID E N T S © STOEY P O IN T S ®
R te 1 2 B
••e m x <w w b v
codemag.com Preparing for Azure with Azure Migrate Application and Code Assessment 41
line, meaning th a t analysis doesn't need to depend on
Visual Studio and can be scripted, i f needed.
Like all .NET SDK tools, the Azure Migrate application and
code assessment CLI to ol is installed using a .NET CLI
Azure Compatibi ity Report
command:
D **^ *^ C 4
S U M M A XV C A ItU V K Iti dotnet tool install -g dotnet-appcat
M
* ________ 9 That command pulls down a NuGet package containing
a______ _______ 9
,______ . . . 9 the latest version of the dotnet-appcat to ol and installs
* _____ _ _____ 9
a______ _______ 9 i t globally. The to ol is run using the appcat command.
,______ . . . 9
a_____ _ i _____ 9 The simplest way to use the Azure Migrate application
a_____ . . . _____ 9
a______ ___ 9 and code assessment CLI is to run appcat analyze solu-
. ________ 9
* 9 tion.sln where solution.sin is the path to the solution or
* _____ _ _ . _ 9
a . „ ___ . . . ____ 9 project file you want to assess. Running analyze without
. ______ _ 9
. _____ _ _ . _ 9 a project or solution specified causes the to ol to search
a_____ _______ 9
. ______ i______ 9 for projects in the current directory. This command starts
a_____ - a . ____ 9
a_____ _______ 9 an interactive command line experience, allowing you to
___ . . . _ 9
a _____ 9 choose which projects from the solution you want to as
a ______ _ _ _ 9
a_____ _ i _____ 9 U U H ’ sess, whether you want to analyze only source code or
a _____ - i ____ 9
a_____ . - a ____ 9 source code and binaries, and what output format you
: ig u t F l t ) f“Assessr^engresults for the eShop sample’ want (HTML, CSV, or JSON)— all the same options as with
a______ - u ___ 9 ~
a ______ 9 the Visual Studio extension! See Figure 12.
a ______ 9
A___ — a - ____ 9
*- ■ i -I r* ii LaiMB 9
Q Those are all of the etected in the eShop sample. Once the appcat CLI to ol gathers the necessary data from
a . __ 9
a______ 9 It's a larger List tha Uy expected, perhaps, but, as you, i t proceeds with analysis and publishes results to a
9
a _______ 9 we thought, the-iss e almost entirely about exter- report using your desired format.
» - - ~ L . . MM 9
a_____________ 9 nal dependencies-th need to be migrated to Azure
a______ ___ 9
, ______ _ .____ 9 along with the eSho ion. There was nothing block- One important note about the CLI experience is th a t
a______ ____ 9
a_. - a 9 ing in the report-exc the helpful reminders th a t the the solution must be able to build w ithout errors. Visual
,________ _____ 9
a _____ ___ 9 solution w ill need-d , message queue, and caching Studio can provide the necessary symbol information for
a_____________ 9
a_____ . - a ____ 9 solutions in the-elo may look different from on- analysis, but when running from the command line in
a________ _____ 9
a______ ____ 9 premises, and previ those (and updating the app stead, the target project must be in a buildable state.
a_. - a 9
._______ 9 to use them) needs Su*** 111
art of the re-platforming plan.
a_____ - I . ____ 9
a_. - a 9 In addition to mimicking the Visual Studio experience,
* n h — ... . L — 9
a______ - a . ___ 9 tu n the Azure Migrate application and code assessment com
a______ ____
a______ . - a ___
9
9
Mun
Using the Co nd Line Interface mand Line to ol accepts parameters th a t allow all decisions
,________ _____ 9 buei
a_____________ 9 In addition to the tudio extension discussed in to be made up-front so th a t the to ol runs completely
a_____ - a____ 9
a _______ 9 the rest of this artic
IJ I
Azure Migrate application and automatically, allowing for a non-interactive experience
a______ ____ 9
* _____________ 9 code assessment fea also available via a .NET com- suitable for scripting. To do this, use the -non-interac
a______ ___ 9
a________ _____ 9 mand Line tool. Th L Studio extension offers the tive parameter and make sure to specify report format
a______ ____ 9
. - L .._ 9 most functionality e the reports maintain state and components to analyze via the command line. Here's
.______ . . . _____ 9
a_____ a - I.____ 9 for which incidents en reviewed), but all the same an example command Line for assessing a C# project non-
a_. - a 9
a _______ 9 assessment capabiliIJI available from the command interactively:
a_____ - a . ____ 9
a_____ — a.____ 9
_______ ___ 9
._______ 9
a_____ . . . ____ 9
a_. . a 9
.______ . . . ____ 9
a_____ .. a . ____ 9
a_____ - u ____ 9
_______ ___ 9
._______ 9
a_____ . . . _____ 9
a_. . a 9
* n h — « ... L — 9
a _____________ 9
a_____ - u ____ 9
>. a^aw . .t e a . Mte 9
v
a _____ . . . _____ 9
a_____________ 9 4UX5
_ 9 t u n ■
» - ■ —________________9
a______ . . . ____ 9
a_ . . a 9
a_ . . . 9
a ______ ____ 9
a_____ . . . _____ 9
a______ ___ 9
._______ 9
a_____ . . . _____ 9
a_ . . a 9
a_ . . . 9
a _____ . . . _____ 9
a_____ — i____ 9
a_____ . - a ____ 9 tim et C
. _____ . . . _____ 9
a_____ . . . _____ 9
a_ . . a 9
a_ . . . 9
a_____ . . . _____ 9
a_____ . - a ____ 9
: ig u te :llrR a bb ith i(t'related
I issues in eShop
9 Q
9 num Q
9 u u m Q
9 u m Q
7
Preparing for Azure with Azure Migrate Application and Code Assessment codemag.com
a_____ _______ 9 iita m O
9 " |1|
9 * '«u<% {7) (1)
appcat analyze eSliopLegacyMVC.cspro] -s HTML
-r OutputPath --cade --non-interactive
Road Map
The Azure Migrate application and code assessment feature
alraadyqjrovides insights necessary to plan a successful Aaure
migration. In theYuture, though, there are even more useful
features planned. Key features coming in future versiens of
Azure Migrate application and code assessment include:
codemag.cQm Preparing for Azure with Azure Migrate Application and Code Assessment 45
ONLINE QUICK ID 2405061
seeing many questions on Linkedln th a t b o il down to , ticle . This w ill be a tw o -p a rt article. Throughout both,
"How do I increase my SQL/database skills to get a data I'm going to m ention some topics th a t I covered in prior
analyst/database developer jo b ? " In th is industry, th a t CODE Magazine articles where the con ten t is s till ju s t as
question is com plicated, as i t means d iffe re n t th in g s to relevant today.
d iffe re n t people. It's arrogant to claim to have a ll the
answers, because doing so would presume th a t someone You can fin d many web articles w ith title s Like, "Here are
knows about every jo b requirem ent o u t there. Having said the 30 best SQL Server in te rvie w questions you should be
th a t, I've worked in th is industry fo r decades, both as an prepared fo r." There are many good ones and I recommend
employee and as a contractor. I'd Like to share w h at skills reviewing them as much as you can. I also recommend
Kevin S. Goff have helped me get and keep a seat a t the table. g e ttin g your proverbial hands d irty inside o f M icrosoft
www. Kevi nSGoff. net SQL Server Management Studio. On th a t note, I'm using
@StagesOfData M icrosoft SQL Server, which means I'LL be covering some
Opening Remarks: M icrosoft-specific topics. Having said th a t, many o f the
Kevin S. Goff is Database A Rebirth o f SQLServer Skills topics in th is article are relevant to other databases.
architect/developer/
Over the last few years, there have been intense opportu
speaker/author, and
nities and jo b growth in the general area o f data analyt I d id n 't w ant to call th is article "The 13 things you should
has been w riting for
ics. That's fan ta stic! There's also been a re a lity check o f study before a SQL interview ," because I'm going beyond
CODE Magazine since
som ething th a t database professionals warned about last th a t. I'm covering w hat I th in k makes for a good SQL/
2004. He was a member of
the Microsoft MVP program decade: the need fo r those using self-service BI tools to database developer. Yes, there's overlap, as I w ant to share
from 2005 through 2019, have some basic SQL and data management skills. As part some o f the specific skills companies are often looking for.
when he spoke frequently o f research, I spent a substantial am ount o f tim e reading
community events in the Linkedln posts, and ta lk in g to recruiters and oth er devel
Mid-Atlantic region and opers about th is , and there's one common them e: There's First, Know Basic SQL
also spoke regularly for s till a boom ing need fo r SQL and data handling skills. I "Know ing basic SQL" is really tw o th in g s: understanding
the VS Live/Live 360 w ant to make a jo ke about being an o ld -tim e SQL person the SQL language (according to the ANSI SQL standard)
Conference brand from and a "boom er," b u t I was born one m onth a fte r the o f and understanding specific features in the database prod
2012 through 2015. fic ia l end o f the boomer generation. uct (in th is article, M icrosoft SQL Server) and some o f the
physical characteristics o f M icrosoft databases. There are
I'm a big sports and music fan and I often hear people talk great books o u t there, b u t these topics tend to come up
about the "DNA" o f great athletes and musicians. In this again and again. I 'l l s ta rt w ith some index basics, even
context, the definition isn 't referring to the biological as before g e ttin g in to some language basics.
pects o f a person. It's more the traits they carry w ith them
and the habits they've burned in to themselves th a t they K now the D iffe re nt Types o f Indexes
leverage regularly to do th e ir jobs and do them well. I cer A common question is the difference between a clustered
ta in ly hope th a t everyone who's w illing to work hard w ill get index and a non-clustered index. W ith th is and other to p
a jo b, and I'm equally excited th a t I've seen a resurgence of ics in th is article, I'm n o t going to w rite o u t a fu ll d e fin i
"w hat SQL Server skills should a data person have?" tio n , because oth er websites have done a great jo b . But
here are th in g s I th in k you should know.
I know people who build great websites and great v i
sualizations in reporting tools, where the available data You can only create one clustered index per tab le and
was very clean and prepared by an existing data team . th a t index defines the sorted order o f the table. For a
However, fo r every one in d iv id u a l jo b o u t there like th a t, sales table th a t m ig h t have m illions o f rows, a clustered
there's more than one jo b where y o u 'll have to p u t on index on e ith e r the sale transaction ID or possibly the
your SQ L/data-handling hat. sales date w ill help queries th a t need to scan over many
rows in a pa rticular order.
I've worn m ultiple hats in the sense th a t I've always had
work. I make mistakes, I underestimate, I s till com m it You can have many non-clustered indexes. They serve
many s illy errors th a t we all, as developers, wish we could the purpose fo r more selective queries: th a t is, fin d in g
avoid. A lthough no one person can possibly cover every sales between tw o dates, fin d in g sales fo r specific prod
possible SQL/data s k ill th a t w ill make someone success ucts, specific geographies, etc. A non-clustered index
fu l, I stepped back and th o u g h t, "W hat has helped me m ig h t contain ju s t one column (com posite index), or i t
to help clients? What has been the difference-m aker on could contain m u ltip le columns i f y o u 'll frequently need
a project?" And th a t's why I decided to w rite th is ar to query on a com bination o f them .
Figure 1: Execution plan, only the execution operator is a Table Scan w ith statistics on the number o f rows read
Figure 2: Execution plan w ith an INDEX SEEK, which is fa r more e ffic ie n t (on ly one row read)
Related: K now When SQL Server W ill Use These Indexes: I f I run the same query again and then Look a t the execu
Ju st because you create an index doesn't mean SQL Server tio n , I'Ll see a very d iffe re n t story: a INDEX SEEKCLUS-
autom atically uses it . For instance, you m ig h t create in TERED INDEX SEEK where SQL Server only needed to read
dexes th a t SQL Server w o n 't use, e ith e r because the SQL one row (Figure 2).
statem ent you're using is n 't search argum ent optim izable
or because you m ig h t n o t realize w hat som ething like Next, I'Ll query the table fo r a ll names where the last
compound indexes w ill (and w on't) do. name is "Richardson".
I'm going to take the table Person.Person from the Ad select * from testperson
ventureWorks database and create my own table. I 'l l also where lastname = 'Richardson*1
create tw o indexes: a clustered index on the prim ary key
(BusinessEntitylD) and a non-clustered index on the Does the clustered index help us a t all? U nfortunately,
Last Name and the First Name. n o t really. A lthough SQL Server scans a clustered index
instead o f a row table (heap), SQL Server must scan a ll
drop table i f exists dbo TestFerson 19,972 rows (Figure 3 ).
go
select * into dbo TestFerson from Person Person To help w ith queries based on a last name, I'Ll create a
non-clustered index on the Last Name column.
Now I 'l l use a single query to retrieve the row fo r a spe
c ific Business E ntity ID: create nonclustered index [ix_LastName]
on TestFerson ( LastName)
select * from TestFerson where BusinessEntitylD
= 12563 A fte r creating the index on Last Name, let's query fo r a
specific Last name, and then fo r a specific Last name and
In the absence o f any index, SQL Server must perform a firs t name:
table scan against the table and read a ll 19,972 rows.
Here's w hat SQL Server returns fo r an execution plan (Fig select * from testperson
ure 1). where lastname = 'Richardson1
A lthough the query runs in a s p lit second, SQL Server had select * from testperson
to read through a ll the rows. It's n o t exactly optim al. where lastname = ‘ Richardson’ and
firstname = 'Jeremy'
Now Let's create a clustered index th a t drives the sort
order o f the table: In the case o f the firs t query, SQL Server uses a more e ffi
cie nt INDEX SEEK on the new index. However, i t does need
create clustered index to perform what's called a KEY LOOKUP in to the clustered
[ix_BusinessEntityClustered] on TestFerson index, to retrieve a ll the columns (because I did a SELECT
(BusinessEntitylD) * to ask fo r a ll the columns).
Figure 3: Execution Plan, now showing a Clustered Index scan on a ll 19K rows
Okay, so a com posite index fu rth e r optim izes the query. "Suppose I have 100 customers in a customer master and
Here's the last question: Suppose I query only on the firs t 100,000 rows in a sales table. You can assume th a t every
name to retrieve a ll the people named Jeremy? W ill SQL sale record is fo r a valid customer. In oth er words, there
Server use the FirstName column from the index and o p ti are no orphaned sales rows. I f I do an INNER JOIN be
mize as w e ll as i t did when I used the last name? Figure tween the rows based on customer ID, how many rows
4 doesn't give us great news. should I expect to get? I f I do a LEFT OUTER JOIN, how
many rows should I expect to get?"
U nfortunately, SQL Server w o n 't perform an INDEX SEEK.
A lthough SQL Server uses the LastNameFirstName index, Yes, th a t's an in te rvie w question flo a tin g o u t there, I kid
i t performs an INDEX SCAN through a ll 19,992 rows. I t you not. The problem is, you d o n 't know i f the person
only finds one " h it " and performs a key Lookup to retrieve is try in g to see w hat oth er questions you m ig h t ask, or
the non-key columns. maybe the person is try in g to see i f the tw o numbers
I
Second, suppose Task A starts and updates one or more of
the tables, but performs a rollback at the end (because of
some post-validation error, etc.). Suppose Task B read the
isolation as versioning.
data using READ UNCOMMITTED ju s t before the rollback. Task
B w ill be returning data th a t never officially saw the lig h t
o f day because Task A rolled i t back. That's also not good! Sounds great, doesn't it? Overall, i t is, although there's
one dow nfall. Suppose Task A com m its its transaction,
These tw o alone should provide caution to developers who b u t Task B is s till in the m iddle o f its READ session o f
use READ UNCOMMITTED. Again, there can be specific in SNAPSHOT. I f Task B queries the row again (in the same
stances (often tie d to w orkflow th ro u g h o u t the course read session), i t continues to return "F air" because i t
For example, I worked on a project where we had some SET ©CategoryBCount = (select count(*) from
pretty significant cost discrepancies between two sys CostDetaiIsLegacy outside
tems. We knew the issues stemmed from code between where MarkedArchive = true
the two systems th a t needed to be refactored. Before we And exists (select 1 from CostProduction inside
could dive into that, we had to come up with a plan where outside.<Keyl> = inside.<Keyl> And
RIGHT AWAY to fix the data. Of course, you can't fix a outside.<Key2> = inside.<Key2> and
problem (or in this case, a myriad of problems) without inside.ConditionForActive = true
identifying all the issues, and th a t was the first order
of business: identifying all the different ways data had Additionally, management might provide an error factor:
gone bad. Maybe i f cost rates differ by Less than two cents (round
ing errors, bad math approaches involving integer divi
Without going into specifics, we found four different sion, etc.), and *maybe* they'll elect to tackle th a t later.
scenarios. Of those four, two of them had sub-scenarios. Once I saw a manager flip out when they saw the top
Some of these were simple and "low-hanging fru it" and of the list of discrepancies sorted by variance and the
some were more complicated. Here were some of them: overall row count. They thought th a t because the top 10
rows were o ff by a large percentage and we had thousands
• Rows in the legacy system marked as deleted/ar- of rows, th a t we had a disaster. I t turns out th a t after
chived, but s till in the production system row 20, the variances dropped to pennies, with a slew of
• Rows in the legacy system marked as deleted, but numbers o ff by ju s t a small amount. So even within your
should not have been categories, check the deviation among the rows.
• Rows in the legacy system with multiple cost com
ponents, where the target system only ever recog I'm not going to devote two pages of code to the specif
nized the first component ics ( it'll ju s t give me flashbacks and nightmares anyway).
I
Certain businesses w ant to take a picture o f the sum o f
antiquated?" here is a proper reply.
transactions over some period. Im agine a bank takin g
"Do you think that all databases a picture o f a ll a person's charges and a ll th e ir depos
built on Kimball fundamentals its during the month and coming up w ith a balance. A
company m ight, as part o f a m onth ending process, read
have suddenly disappeared?" across a ll the bank transactions and w rite o u t a periodic
Knowing how to implement Kimball snapshot table th a t holds the account ID, m onth ID, sum
o f charges, some o f deposits, and the balance. Let's say
ideas will be relevant for a LONG
they do th a t fo r three months and so the snapshot fa ct
time. Its not a technology, table holds three rows. Can you sum the numbers fo r the
it's not a language: It's a collection charges and deposits in to som ething m eaningful? In th is
case, yes. Can you sum the balance fo r each o f the three
of approaches, and an outstanding months? Well, much as you m ig h t Like th a t, the balance
one that that. is n 't cum ulative. Unlike the fir s t tw o measures, the bal
ance is n 't fu lly additive. Yes, you could take an average
o f it , which means th a t measure is sem i-additive, and
n o t cum ulative. Periodic snapshot fact tables are not
There are many d iffe re n t data warehousing concepts, bu t uncommon.
here are a few you should know:
There's also a th ird type o f fa c t table, usually in vo lvin g an
First, w hat are Fact Tables and Dimension Tables? a c tiv ity where you're n o t Looking to sum up numbers (like
Loosely speaking, Fact Tables represent a c tiv ity /b u s i- sales or number o f item s produced) b u t merely counting
ness processes. They could be sales, returns, transactions, the number o f tim es som ething happened. For instance,
m anufacturing production and quality, or even survey let's say I teach tw o classes a day. Yesterday, 28 o u t o f
evaluations: SOMETHING happened, and you w ant to ana 30 attended Class A, and 18 o u t o f 19 attended Class
lyze those som ethings over tim e. They could occur five B. The next day, the numbers are 29 o u t o f 30, and 17
m illio n tim es a day or ju s t 100 tim es a week. Last n ig h t, o u t o f 19, respectively. You m ig h t have a Factless fa ct
I bought some new a rt supplies fo r my daughter— th a t table th a t records no thin g more than the number o f tim es
transaction m ig h t very w e ll be s ittin g in a fa c t table. More som ething happened (attendance fo r a pa rticular class
on th a t in a m inute. by a pa rticular in stru cto r). A ll you really get o u t o f the
Factless fa c t table is the count, although th a t count over
Dimension tables represent the business e n titie s th a t are tim e (or average) m ig h t have analytic value.
associated w ith the a c tiv ity m entioned above. I bought
the supplies a t a certain tim e o f the evening from a store Okay, I'm going to bring up one more to p ic th a t's likely
in a pa rticular sales d is tric t th a t belongs to a certain to come up during an interview : slowly-changing dim en
sales region. The products were specific a rt supplies made sions. Here's how I describe it : suppose a product was
by a certain company and came in certain packaging. introduced in 2022 and sold in a ll o f 2022 fo r a manu
facturer price o f $50. On 1 /1 /2 0 2 3 , the price increased
Here's the single most im p o rta n t word in data warehous to $52. Then on 7 /1 5 /2 0 2 3 , the price increased to $53.
in g: the word "b y ." Sales departments w ant to see the
rollup o f sales dollars "b y " city, "b y " customer type, "b y " Here's the big question: Do you care about tracking sales
da te/m on th or even "b y " tim e o f day, "b y " product manu during the tim e when the product was $50, versus $52,
facturer and product type. So those core id e n tifie rs th a t versus $53?
were part o f the sale (the exact d a te /tim e , the customer
ID, the product UPC, the store ID and maybe even sales Here's another example. From the tim e I started paying
register number) belong to larger groups. taxes (i.e ., age 18, fir s t jo b ), I've Lived a t 10 d iffe re n t
addresses (kind o f scary to th in k about it ) . Let's say some
I f the product was a seasonal item , sales m ig h t w ant to governm ent agency tracks in fo rm atio n about me. Do they
track sales across years by season (seasonality), where care i f was a resident in one area fo r X years/m onths and
the actual dates m ig h t vary a b it. ( I Like to use the classic another area fo r a d iffe re n t am ount o f tim e?
example o f tracking sales o f fish foods during Lent each
year, where Lent can be d iffe re n t weeks each year). When you care about aggregating fa ct data n o t only by
an a ttrib u te (a product ID or a Social Security Number),
Now, you can look up fa c t tables and dimension tables b u t by changes to th a t a ttrib u te th a t have occurred over
and fin d several equally valid d e fin itio n s. This is one o f tim e, you refer to th a t as a Type 2 Slowly Changing Di
the reasons I detest unqualified people doing interview s mension.
SPONSORED SIDEBAR P ro g ra m m in g -P u zz le -Y o u -N e v e r-S to p -L e a rn in g file s w ith s ta tis tic s . Yes, i t to o k som e w o rk to assem ble
• A Power B I a rtic le : th o s e in t o m e a n in g fu l databases, b u t i t was w o rth i t . I f
Ready to • Stages o f D ata: COVID D ata, S um m ary Dash y o u 're s ta r tin g o u t a t a new jo b , o r even a p p ly in g fo r a
boards, and Source Data Tips ( c o d e m a g .c o m ) new jo b , y o u w a n t p e o p le to w a tc h y o u do s o m e th in g and
Modernize a
• Four a rtic le s on SQL S erver re p o rtin g S ervices: say, "W ow, t h a t person has o b v io u s ly done th is b e fo re ."
Legacy App? • h ttp s ://c o d e m a g .c o m /A r tic le /1 8 0 5 0 5 1 /
R e fa c to rin g -a -R e p o rtin g -S e rv ic e s -R e p o rt-w ith -
Need advice on migrating
yesterday's legacy Som e-SQ L-M agic
Summary: What I Almost Called
applications to today's • h t t p s : / / c o d e m a g . c o m / A r t ic le / 1 7 1 1 0 6 1 / S Q L - This Article
modern platforms? Take S erver- R e p o rti n g -S e rvi ces- Ei g h t - Po w e r-T i ps I'v e been w o rk in g on th is a rtic le fo r o v e r fo u r m o n th s. As
advantage of CODE • h t t p s : / / c o d e m a g . c o m / A r t ic le / 1 7 0 5 0 6 1 / S Q L - m o s t a u th o rs can a tte s t, w h a t y o u s ta r t w ith and w h a t
Consulting's years of S e rve r-R e p o rtin g -S e rvice s-S e ve n -P o w e r-T ip s y o u fin is h w ith can be d iffe r e n t th in g s . As I lo o k back
experience and contact • h t t p s : / / c o d e m a g . c o m / A r t ic le / 1 6 0 5 1 1 1 / S Q L - o ve r th is , th e c o n te n t it s e lf d id n 't change m uch, b u t th e
us today to schedule a S erver- R e p o rti n g -S e rvi ces- Ei g h t - Po w e r-T i ps reasons I w ro te i t e v o lve d . As I m e n tio n e d e a rlie r, I'v e
FREE consulting call to seen m any L in k e d ln q u e s tio n s w here s o m e th in g Like th is
discuss your options. I'v e cre a te d d a ta p ro je c ts and dashbo ard pages fro m p e r w o u ld be h e lp fu l. I also w ro te th is because I w a n te d to
s o n a l d a ta fo r e v e ry th in g fro m m y w e e k ly h e a lth s ta ts to share w h a t th in g s I'v e seen m any tim e s . I'LL ne ve r c la im to
No strings. No
p e rs o n a l fin a n c e s . The m ore y o u p ra c tic e , th e b e tte r! have a ll th e answ ers on w h a t makes a go od datab ase de
commitment.
ve lo p e r, b u t I'v e in s tru c te d p e o p le a t a te c h s c h o o l w hose
It's g re a t t o read and absorb in fo rm a tio n fro m w e b s ite s m issio n was to h e lp p e o p le g e t jo b s (o r g e t b e tte r jo b s )
For more information,
w w w .c o d e m a g .c o m / and books. Yes, so m e tim e s it 's because y o u 're tr y in g to and I'v e m e n to re d o th e r d e ve lo p e rs. I alw ays w a n te d to
c o n s u ltin g or email us at so lve a s p e c ific p ro b le m a t w o rk , so y o u a lre a d y kno w ta k e an in v e n to ry o f w h a t fu n d a m e n ta ls I t h in k o th e rs
in fo @ c o d e m a g .c o m . y o u 're g e ttin g y o u r hands d ir t y and y o u ju s t need t o how w ill fin d im p o rta n t, ju s t t o make sure I h a d n 't fo rg o tte n
t o use y o u r hands. O th e r tim e s , y o u m ig h t be research a n y th in g (a n d I'Ll fre e ly a d m it t h a t I'd fo rg o tte n th e spe
in g o r Learning a to p ic w here y o u h a v e n 't g o tte n y o u r c ific s o f F ill F a cto r). I also kn o w som eone w ho's c o n s id e r
hands d irty . ALL Learning is k in e tic in som e w a y— a person in g a career in th is in d u s try . I'v e been su cce ssfu l in m y
c o u ld read a b o o k on ho w t o p e rfo rm open h e a rt surgery career: I'v e made m any m ista ke s, and I'v e Learned hard
100 tim e s and be a b le to q u o te each Line in th e b o o k, lessons as w e ll! I w a n te d to lo o k back on w h a t areas o f
fo r in s ta n c e . W ell, I'm n o t sa y in g t h a t im p le m e n tin g a kn o w le d g e have helped me to be succe ssful.
Type 2 c h a n g in g d im e n s io n is open h e a rt surgery, b u t
th e m ore y o u can d e m o n s tra te to o th e rs t h a t y o u CAN I'v e been ta lk in g to a d e v e lo p e r t h a t I m e n to re d fo r a fe w
do s o m e th in g .... As som eone w ho 's in te rv ie w e d p e o p le , I years. T h e ir f ir s t response was, "W ow , y o u 're re a lly tr y in g
m ig h t fin d som eone's p e rs o n a l exa m ple (a go od e xa m ple ) to expose in te r v ie w e r s !!!" As Eric Id le said t o J o h n Cleese
o f im p le m e n tin g a Type 2 SCD, o r som eone b e in g a b le to d u rin g th e fam ous "N ud ge Nudge W in k W in k " s k it: "O h no,
open tw o qu e ry w in d o w s w ith a te s t ta b le t o d e m o n s tra te no , no , (p a u s e ), YES!"
READ COMMMITTED SNAPSHOT, to be ve ry c o m p e llin g .
There are to p ic s I covered in th is a rtic le in m ore d e ta il
th a n o th e rs . I w e n t in t o a f a ir a m o u n t o f d e ta il on th e
One Thing I Won't Talk About S n a p s h o t Is o la tio n Level, b u t o n ly b r ie fly ta lk e d a b o u t
(But One Final Thing That I Will) Change Data C apture and lo g g in g . There are o th e r w eb
There are o th e r g re a t to o ls and te c h n o lo g ie s th a t database a rtic le s o u t th e re , in c lu d in g som e fro m me. As I'v e lin k e d
developers use. One t h a t comes to m ind is P ython. Database in th is a rtic le , th e re w ere som e to p ic s t h a t I'v e p re v io u s ly
developers w ho also w ork on th e .NET side w ill som etim es covered in CODE M agazine and d id n 't w a n t to re p e a t.
use E n tity Framework. Those w ho w ork on th e ETL side m ig h t
use th ird -p a rty to o ls such as COZYROC and possibly d iffe re n t Kevin S. G o ff
M aster Data M anagem ent to o ls . The List goes on and on. CODE
th a n SOAP o r REST a lo n e . This a rtic le aim s to p ro v id e a t h a t a llo w s d iffe r e n t a p p lic a tio n s to in te r a c t w ith one a n
co m p re h e n sive o v e rv ie w o f th e e v o lu tio n o f w eb A PIs, o th e r o ve r a n e tw o rk by Leveraging XML as th e message
e x p lo rin g th e tra n s itio n fro m SOAP to REST, and fin a lly fo rm a t. You can ta k e a d va n ta g e o f SOAP t o b u ild in te r o p
to GraphQL. I t w ill d e lve in t o th e m o tiv a tio n b e h in d each era b le w eb services t h a t w o rk w ith d is p a ra te te c h n o lo g ie s
a r c h ite c tu ra l s ty le , and t h e ir c h a ra c te ris tic s , b e n e fits , and p la tfo rm s . The s tru c tu re and c o n te n t o f XML m es
and draw backs. By u n d e rs ta n d in g th e pro g re ssio n fro m sages, as w e ll as a s e t o f c o m m u n ic a tio n g u id e lin e s , are
SOAP to REST and th e em ergence o f GraphQL, d e velop ers o u tlin e d in a SOAP d o c u m e n t.
can m ake in fo rm e d d e cisio n s w hen c h o o s in g th e r ig h t A P I
design fo r th e ir p ro je c ts . N ote t h a t ASP.NET Core d o e s n 't have any b u ilt - in s u p p o rt
fo r SOAP. R ather, th e .NET Fram ew ork p ro vid e s b u ilt - in Joydip Kanj i lai
I f y o u 're t o w o rk w ith th e code exam ples discussed in th is s u p p o rt fo r w o rk in g w ith ASMX and WCF. U sing th ir d - p a r j oy di p ka n ji LaL@y a h o o . co m
a rtic le , y o u need th e fo llo w in g in s ta lle d in y o u r syste m : t y lib ra rie s , y o u can s t i l l b u ild a p p lic a tio n s t h a t Leverage
Jo yd ip K a n jila l is an MVP
SOAP in ASP.NET Core. Figure 1 d e m o n stra te s how SOAP
• V isu a l S tu d io 2022 w orks. (2 0 0 7 -2 0 1 2 ), softw are
a rc h ite c t, author, and
• .NET 8 .0
speaker w ith more tha n
• ASP.NET 8 .0 R un tim e
Anatomy of a SOAP Message 20 years o f experience.
He has more th a n 16 years
I f y o u d o n 't a lre a d y have V is u a l S tu d io 2022 in s ta lle d on A SOAP (S im ple O b je ct Access P ro to co l) message is an XML-
o f experience in M icrosoft
y o u r c o m p u te r, y o u can d o w n lo a d i t fro m here: h t t p s : / / based s tru c tu re used to exchange in fo rm a tio n betw een web
.NET and its related
v is u a ls tu d io .m ic ro s o ft.c o m /d o w n lo a d s /. services across diverse n e tw orks and p la tfo rm s . A ty p ic a l
tech no lo gies. Jo yd ip has
SOAP message is com prised o f several ele m en ts t h a t d e fin e
authored e ig h t books,
In th is a rtic le , I ’l l exa m ine th e fo llo w in g p o in ts : th e message's stru c tu re , c o n te n t, and o p tio n a l fe a tu re s. more th a n 500 articles,
SOAP messages are designed to be e xte n sib le , n e u tra l, and and has reviewed more
• SOAP, REST, and GraphQL and t h e ir b e n e fits in d e p e n d e n t o f any s p e c ific p ro g ra m m in g m o del o r tra n s th a n a dozen books.
• The key differences betw een SOAP, REST, and GraphQL p o rt p ro to c o l, ty p ic a lly HTTP o r HTTPS.
• The b e n e fits and drawbacks o f SOAP, REST, and GraphQL
• H ow to use each o f th e s e to o ls in e n te rp ris e apps A ty p ic a l SOAP message com prises fo u r key e le m e n ts, as
S ^E ■ ■■ ■ ■ ■ ■_
show n in Figure 2.
A fte r g a in in g th is kn o w le d g e , y o u 'll b u ild th re e a p p lic a
tio n s : one each u sin g SOAP, REST, and GraphQL. • E nvelope
• H eader (o p tio n a l)
• Body
What Is Simple Object Access • F a u lt
Protocol (SOAP)?
S im p le O b je c t Access P ro to c o l (SOAP) is a c o m m u n ic a tio n T his n e x t s h ip p e t is ho w th e s tru c tu re o f a ty p ic a l SOAP
p ro to c o l fo r d a ta exchange in a d is tr ib u te d e n v iro n m e n t message lo o ks:
SOAP Message
SOAP Response
SOAP Envelope
Every SOAP message is encapsulated inside a roo t elem ent POST /ProductPrice HTTP/1.1
called SOAP Envelope. I t defines the XML namespace and
Host: www.example.org
contains tw o mandatory child elements: the SOAP Header
Content-Type: application/soap+xml;
and the SOAP Body.
charset=utf-8
Content-Length: nnn
<soap:Envelope
<?xml version="1.0"?>
xmlns:soap=
"http://www.w3.org/2003/05/soap-envelope/" <soap:Envelope
xmlns:soap=
soap:encodingStyle=
"http://www.w3.org/2003/05/soap-encoding"> "http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle=
"http://www.w3.org/2003/05/soap-encoding">
SOAP Header
The SOAP Header is an o p tio n a l elem ent th a t contains
<soap:Body xmlns:m=
a d d itio n a l in fo rm atio n or metadata about the SOAP mes
"http://www.abcxyz.org/product">
sage, such as au the ntica tion credentials, security tokens,
<m:GetProductPrice>
or rou ting instructions.
<m:ProductCode>HP_Envy_i9</m:ProductCode>
</m:GetProductPrice>
<soap:Header>
</soap:Body>
<!-- Optional SOAP Header elements -->
</soap:Header>
</soap:Envelope>
<soap:Body> <env:Header>
<!-- SOAP Body content --> </env:Header>
</soap:Body>
<env:Body>
SOAP Fault </env:Body>
During the processing o f a SOAP message, an o p tio n a l
elem ent called SOAP Fault can be used to convey error or </env:Envelope>
fa u lt in fo rm atio n back to the c lie n t in case o f errors or
exceptions th a t occur during the process. And here's how a SOAP response to the above SOAP re
quest Looks:
<soap:Fault>
<!-- Fault details --> HTTP/1.1 200 OK
</soap:Fault> Content-Type: application/soap+xml;
<?xml version="1.0"?>
<soap:Envelope
xmlns:soap=
"http://www.w3.org/2003/05/soap-envelope/"
soap:encodingStyle=
"http://www.w3.org/2003/05/soap-encoding">
• Service provider: This is the com ponent th a t pro DataContract and ServiceContract
vides the web service and encompasses the applica In SOAP, DataContract and ServiceContract are key con
tio n its e lf, the platform on which the application cepts used to define the structure o f data and the opera
executes, and the middleware. tions supported by the service.
[ServiceContract] [DataContract]
public interface IMyDemoService public class Customer
{ {
[Operationcontract] [DataMember]
string GetText(int id); public int Id { get; set; }
} [DataMember]
public string FirstName { get; set; }
[DataMember]
Im p le m e n t a SOAP Service in public string LastName { get; set; }
ASP.NET Core [DataMember]
In th is section, I 'l l examine how to bu ild a SOAP service public string Address { get; set; }
in ASP.NET Core. The section th a t follow s outlines the }
series o f steps needed to create a new ASP.NET Core Web
API project in Visual Studio. Create the Custom erRepository
The CustomerRepository class extends the ICustomerRe-
Create a NewASP.NET Core 8 Project in Visual Studio 2022 pository interface and im plem ents its methods, as shown
You can create a project in Visual Studio 2022 in several in the code given in Listing 1.
ways. When you Launch Visual Studio 2022, you’ll see the
S tart window. You can choose "Continue w ith o u t code" Create the Service C ontract
to Launch the main screen o f the Visual Studio 2022 IDE. To create a service contract, create an interface called
ICustomerService and w rite the code given in Listing
To create a new ASP.NET Core 8 Project in Visual Studio 2022: 2 in there. The CustomerService class extends the ICus-
using CustomerServiceReference;
ICustomerService soapServiceChannel =
new CustomerServiceClient
(CustomerServi ceCli ent.
Back Next Cancel
Endpointconfiguration.
Basi cHttpBi ndi ngJCustomerServi ce_soap);
Figure 4: Adding a new Service Reference var response = await soapServiceChannel.GetCustomersAsyncO;
Client-Server A rchitecture
As a rule o f thum b, a RESTful architecture should be
W hat Are REST APIs?
based on a client-server architecture. A lthough the c li H ow Do They Work?
en t requests resources from the server, the server pro REST APIs communicate data between c lie n t and server
vides resources as appropriate to the authorized clients. using HTTP requests. Once a c lie n t sends a request, the
reduced performance and im proper or in e ffic ie n t use and the types o f operations (queries and m utations)
o f memory, CPU, and network resources. th a t can be performed, thereby helping w ith valida
• Versioning: Versioning in REST APIs manages chang tio n and introspection.
es to the APIs by assigning diffe ren t versions, such as • Improved performance: For applications th a t re
v l, v2, and so on. GraphQL elim inates the necessity quire complex queries com bining m ultiple resources,
fo r version control by allowing clients to specify the GraphQL can be more e ffic ie n t than REST because i t
data they need in the query, making i t easier fo r APIs can gather a ll data in a single request.
to evolve w ith o u t breaking the existing queries. APIs
b u ilt w ith GraphQL do not require separate version There are certain downsides as w ell:
ing because clients or API consumers can define th e ir
requirements in the query and fetch the required data • Learning curve: Despite its simplicity, GraphQL is quite
w ith o u t breaking the existing queries. complex for those who are unfamiliar w ith its concepts.
• Type System: GraphQL employs a strongly typed The Learning curve for designing schemas, resolving
schema specifying the data form at you can request. queries, and securing GraphQL APIs can be quite steep.
This schema functions as a consensus between the • Caching challenges: Due to the dynamic nature o f
c lie n t and the server, thereby enabling the early de GraphQL queries, client-side and server-side caching
te ctio n o f errors. By recognizing p o te n tia l errors up can be more challenging compared to REST, where
fro n t, you can resolve the errors in a planned way URLs can easily serve as cache keys.
before they im p act your clients. • Increased complexity: GraphQL adds more complex
ity to the server-side im plem entation in contrast to
conventional REST APIs. You should use resolvers to
Benefits and Downsides of GraphQL get the data you need. Managing complex queries
Here are the key benefits o f GraphQL: m ig h t in cur a d d itio n a l e ffo rt.
• Rate lim itin g : Im plem enting rate lim itin g in
• Efficient data querying: With GraphQL, clients can GraphQL is more complex than in REST because it's
query m ultiple resources and retrieve related data in harder to predict the cost o f a query due to its fle x
a single request. They can traverse the data graph ib le nature.
and retrieve only the required data, avoiding the • Security considerations: GraphQL APIs must be
over-fetching o f unnecessary fields or nested objects. carefully designed to avoid p o te n tia l vulne rab ilities.
• Reduced network traffic: GraphQL reduces the net Exposing to o much data or fu n c tio n a lity through the
work tra ffic and bandwidth consumption by m inim iz API can increase the attack surface, making proper
ing the payload size o f the responses. This explains au the ntica tion and authorization crucial.
why applications th a t Leverage GraphQL often e xh ib it
better performance compared to RESTful applications.
• Versioning and evolution: W ith GraphQL, depre GraphQL vs. REST
cated fields or types can be marked to signal clients A lthough REST and GraphQL are tw o o f the most popular
fo r m igration, allow ing fo r smooth API evolution approaches fo r bu ildin g APIs, there are subtle differences
w ith o u t breaking existing clients. between the tw o:
• Support fo r re al-tim e data: W ith GraphQL subscrip
tions, clients can subscribe to specific data changes • Request form at: Each endp oint in REST specifies a
in real-tim e. Once subscribed, the clients are n o ti set o f resources and operations, and the c lie n t can
fied using events about any changes made to the typ ic a lly retrieve or m odify a ll resources using HTTP
data in real-tim e. methods, such as GET, POST, PUT, or DELETE. With
• Strongly typed schema: GraphQL enforces a robust GraphQL, clients request data based on a specific
typ in g system and a w ell-defined schema, providing structure th a t matches the server's schema.
c la rity fo r the available data types and fields. The • Data Retrieval: Each resource in REST can only
GraphQL schema defines the structure o f the data be accessed through a particular endpoint, mean-
using HotChocolate.Subscriptions; {
List<Store> stores =
namespace GraphQL_Demo await StoreRepository.GetStoresO;
{ await eventsender.SendAsync
public class StoreQuery ("Returned a List of Stores", stores);
{ return stores;
public async Task<List<Store>> }
GetAllStores( [Service] }
IStoreRepository StoreRepository, }
[Service] ITopicEventSender eventsender)
in each o f these fields can be traversed and retrieved by Create a GraphQL Subscription
nesting them . Create a new .cs file named StoreQuery in You should also create a subscription to enable your
your project and replace the de fau lt generated code w ith GraphQL server to n o tify a ll subscribed clients when an
the code given in Listing 7. event occurs. Create a new class named StoreSubscription
and replace th e de fau lt generated code w ith the source
Create the GraphQL Object Type code given in Listing 9.
In GraphQL, Object Types are used to describe the type of data
fetched using your API and they are represented by creating Configure GraphQL Server in ASP.NETCore
a class th a t derives the GraphQLJypes.ObjectGraphType class. Once you've created the Query type to expose the data
Create a new file named StoreType.es in your project and re you need, you should configure GraphQL Server in the
place the default code w ith the code given in Listing 8. Program.es file using th e fo llo w in g code snippet:
O D focalhost
S
C
O
D
A
M
E
H
C
S
using GraphQL_Demo;
using HotChocolate.AspNetCore; var app = builder.BuildQ;
using HotChocolate.AspNetCore.Playground;
11 Configure the HTTP request pipeline.
var builder = WebApplication.CreateBuiIder(args);
app.UseAuthorization();
// Add services to the container.
builder.Services.AddScoped app.MapControllers();
<IStoreRepository, StoreRepository>(); app.UsePlayground(new PlaygroundOptions
{
builder.Services.AddGraphQLServer() QueryPath = "/graphql",
.AddType<StoreType>() Path = "/playground"
.AddQueryType<StoreQuery>() });
.AddSubscriptionType<StoreSubscription>()
.AddlnMemorySubscriptions(); app.MapGraphQLO;
app.Run();
builder.Services.AddControllers();
[Route("api/[controller]")]
[ApiController]
public class Storecontroller : ControllerBase Group Publisher
Markus Egger
{
private IStoreRepository _storeRepository; Editor-in-Chief
public Storecontroller Rod Paddock
(IStoreRepository storeRepository)
Managing Editor
{
_storeRepository = storeRepository; Ellen W hitney
} Content Editor
Melanie Spiller
[HttpGet("{id}")]
public async Task<Store> GetStore(int id) Writers in This Issue
Markus Egger Kevin Goff
{
return await _storeRepository.GetStore(id); Joydip Kanjilal Julie Lerman
Sahil Malik Mike Rousos
}
Paul D. S heriff
[HttpGet("GetStores")] Technical Reviewers
public async Task<List<Store» GetStoresO Markus Egger
{ Rod Paddock
return await _storeRepository.GetStoresO;
Production
}
Friedl Raffeiner Grafik Studio
}
w w w .frigraf.it
}
Graphic Layout
Friedl Raffeiner Grafik Studio in collaboration
w ith onsight (www .onsightdesign.info)
Listing 10 shows the complete source of the Program.es file.
Printing
Fry Communications, Inc.
Now execute the application and browse the /playground 800 West Church Rd.
endpoint. Next, execute the following query: Mechanicsburg, PA 17055
Advertising Sales
query Tammy Ferguson
832-717-4445 ext. 26
{ [email protected]
storeByld (id: 1)
Circulation & Distribution
{ General Circulation: EPS Software Corp.
id Newsstand: Ingram Periodicals, Inc.
name In te rn a tio n a l Bonded Couriers (IBC)
Media Solutions
address Source In te rlin k In te rn a tio n a l
}
Subscriptions
}
Circulation M an ag er
Colleen Cade
Figure 9 shows the output on execution of the application. 832-717-4445 ext. 28
[email protected]
Create the StoreController Class
US subscriptions are $29.99 USD fo r one year.
Finally, you need to build the controller class to expose Subscriptions outside the US are $50.99 USD.
the endpoints to the outside world so th a t they can be Payments should be made in US dollars drawn
consumed by the authenticated clients or consumers of on a US bank. American Express, MasterCard,
Visa and Discover credit cards accepted.
the API. To do this, create a new API Controller in your Back issues are available. For subscription
project named StoreController and write the code given in inform ation, email subscriptions@ code-magazine.com
Listing 11 in there. or contact customer service a t 832-717-4445 ext. 9.
Subscribe online at
www.code-magazine.com
Conclusion
CODE Developer Magazine
The requirements and constraints of your project w ill de EPS Software Corporation / Publishing Division
termine the most appropriate choice between SOAP, REST, 6605 Cypresswood Drive, Ste 425, Spring, Texas 77379 USA
Phone: 832-717-4445
or GraphQL. SOAP is a good choice for enterprise-level
applications because of better support for security and
its robust contract definitions. REST can significantly
enhance a resource-oriented application because of bet
ter performance, enhanced scalability, and simplicity.
GraphQL offers a flexible, efficient approach to data re
trieval and manipulation, making i t an excellent choice
for applications th a t require strong typing, real-time data
updates, and efficient data retrieval capabilities.
Joydip Kanjilal
CODE
UNLOCK ±
STAFFING ~
EXCELLENCE
Top-Notch IT Talent, Contract Flexibility, Happy Teams, and a
Commitment to Customer Success Converge with CODE Staffing
Our IT staffing solutions are engineered to drive your business forward while
saving you time and money. Say goodbye to excessive overhead costs and
lengthy recruitment efforts. With CODE Staffing, you'll benefit from contract
flexibility that caters to both project-based and permanent placements. We
optimize your workforce strategy, ensuring a perfect fit for every role and
helping you achieve continued operational excellence.
Visit our website to find out more about how we are changing
the staffing industry.
Website: codestaffing.com
Yair Alan Griver (yag)
Chief Executive Officer
Direct: +1 425 301 1590
Email: [email protected]