<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Laurent Bugnion</title>
    <description>The latest articles on Forem by Laurent Bugnion (@lbugnion).</description>
    <link>https://forem.com/lbugnion</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F140274%2F31133bce-c9b3-4949-a9b4-f13cb558acbe.jpg</url>
      <title>Forem: Laurent Bugnion</title>
      <link>https://forem.com/lbugnion</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/lbugnion"/>
    <language>en</language>
    <item>
      <title>Humans of Microsoft S02E01: Abel Wang</title>
      <dc:creator>Laurent Bugnion</dc:creator>
      <pubDate>Mon, 02 Aug 2021 14:24:22 +0000</pubDate>
      <link>https://forem.com/azure/humans-of-microsoft-s02e01-abel-wang-263a</link>
      <guid>https://forem.com/azure/humans-of-microsoft-s02e01-abel-wang-263a</guid>
      <description>&lt;p&gt;A few weeks before Abel Wang's passing, he accepted my invitation to talk about his relocation from the Midwest to Redmond, his favorite software project ever, and his attitude towards life and his health issues.&lt;/p&gt;

&lt;p&gt;Because of the circumstances, and after talking to Abel's family, we decided to publish this video now to remind everyone of Abel's amazing energy and positivity. We miss you Abel.&lt;/p&gt;

&lt;p&gt;This is part of a series titled Humans of Microsoft, which is part of the Hello World show on LearnTV and on Channel9.&lt;br&gt;
More details here&lt;br&gt;
&lt;a href="https://dev.to/t/humansofmicrosoft"&gt;https://dev.to/t/humansofmicrosoft&lt;/a&gt;&lt;br&gt;
and here&lt;br&gt;
&lt;a href="https://channel9.msdn.com/Shows/Hello-World"&gt;https://channel9.msdn.com/Shows/Hello-World&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/xCkcKMRrp7s"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Transcript
&lt;/h2&gt;

&lt;p&gt;Laurent: Welcome back to Humans of Microsoft. This is a segment where we talk to people just like you and me, but they all happen to work for Microsoft and today I have a guest who is not really just like you and me because it's a, it's an actual rock star and I'm so happy to welcome my good friend Abel Wang to the show. Hello Abel, how are you?&lt;/p&gt;

&lt;p&gt;Abel: I'm doing really good. Thank you so much for having me.&lt;/p&gt;

&lt;p&gt;Laurent: Oh absolutely, such a pleasure to have you. And as a first guest of Season 2, Abel, you are a Principal Program Manager and you work for Azure Incubations, right?&lt;/p&gt;

&lt;p&gt;Abel: Yes, that is correct. I'm officially the technical advisor to the CTO of Azure, so to Mark Russinovich.&lt;/p&gt;

&lt;p&gt;Laurent: So Abel I know that a few years ago you were living in Houston and you moved to the Pacific Northwest So in the region of Seattle, which is, you know, the headquarters of Microsoft. Why did you decide to move and how do you feel that it impacted your career?&lt;/p&gt;

&lt;p&gt;Abel: That's a great question. I actually, I've always wanted to make it to the West Coast. Well I grew up in the Midwest in the United States, but I wanted to be in California, 'cause clearly that's where I belong. Or somewhere on the West Coast. I definitely didn't belong in the Midwest, but when I graduated from college, I already had my son then. So money was really tight. And you know, I got, I got a CS degree, And I got job offers on the East Coast, West Coast, everywhere, but they all paid the same amount of money. But living in Houston, TX, that was, the cost of living is so cheap, it was kind of a no brainer. So my plan was, move to Houston and then in a couple years I'll find a job somehow and get to the West Coast. But what I didn't realize is once you have children, you're kind of stuck in a place, right? So as soon as my son graduated from high school, I looked at my wife. She looked at me and we said, now is the time right? And I knew I wanted to spend a little bit of time in Redmond, at least just because that's the corporate headquarters for Microsoft and I wanted to be where the action was. I wanted to see what it was like. You know, I knew that I could compete in Microsoft everywhere else, right around the world, doing services, doing sales. But I was like, can I compete with those Redmond people, but then, can I join, like, a product group? Can I? Am I at that level? Can I do this? It was like a challenge. And it was a strategic move on my part in terms of what I wanted for my career. So I actually got a job in product marketing. And I moved over to Seattle and it was amazing coming into work, going into campus every single day, it was, it was freaking amazing. The amount of connections that I built was invaluable, right, the face-to-face time. I think it was a huge positive influence on my career and I'm not saying that it's the only way to do things, but for me, I'm I'm glad I made the move.&lt;/p&gt;

&lt;p&gt;Laurent: What production software that you wrote are you the proudest of?&lt;/p&gt;

&lt;p&gt;Abel:  That's another great question. I think I need to go all the way back in time to, this was my third year out of college. I somehow fooled Chase Bank into thinking that I was actually like a software architect of some sort, and at that time, this was during the dotcom boom. So everybody was getting jobs, but I was, we were trying to get bank information except they stored all their bank information on mainframes, right? So in order to have web servers that could serve a webpage that would pull that live information from the mainframe. Well, that was really tough. They didn't have a way to do that, so if you remember back, I guess this would be the early 90s, or mid 90s there, there really was very few ways that you could remote and do things right, so I ended up having to write a bridge using CORBA. That would talk to both the mainframe and to, like, the web servers to pull data from the main frames. And it's still being used by Chase today. So it was one of my first big projects and one of the funnest things I've done.&lt;/p&gt;

&lt;p&gt;Laurent: Wow, CORBA, it's like a horror show for me.&lt;/p&gt;

&lt;p&gt;Abel: Oh it was horrible. But I didn't know better back then.&lt;/p&gt;

&lt;p&gt;Laurent: Well yeah, I mean back then it was the way, right? So quickly to finish and we could talk, you know, for many more hours probably, but how do you stay positive throughout everything that you're going through?&lt;/p&gt;

&lt;p&gt;Abel: Very good question. So for those that don't know, I was diagnosed with cancer about three years ago and then I beat it. And then in March I was diagnosed with stage four cancer and it spread everywhere, right? So people often ask me, how do you stay positive? But the truth is, life is hard for all of us. All of us, it's hard, right? in in in some certain ways, and you can't wait until life isn't hard enough to decide to be happy. So I decide to be happy every day that I can.&lt;/p&gt;

&lt;p&gt;Laurent:  Wow. This is fantastic. Positivity as a decision, as a conscious decision. I love that. Well, this was fantastic. Thank you so much for coming on the show today, Abel, it was amazing. Thank you so much to all the viewers for watching and we'll see you next time on Humans of Microsoft.&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>humansofmicrosoft</category>
      <category>helloworld</category>
    </item>
    <item>
      <title>Humans of Microsoft S01E02: Tasha Scott</title>
      <dc:creator>Laurent Bugnion</dc:creator>
      <pubDate>Fri, 02 Jul 2021 10:35:33 +0000</pubDate>
      <link>https://forem.com/azure/humans-of-microsoft-s01e02-tasha-scott-2o4n</link>
      <guid>https://forem.com/azure/humans-of-microsoft-s01e02-tasha-scott-2o4n</guid>
      <description>&lt;p&gt;Humans of Microsoft is not about tech, it's about humans just like you and me, but they all work for Microsoft. Discover a new guest every week in this series, either live on &lt;a href="https://aka.ms/learntv"&gt;Learn TV&lt;/a&gt; or on the &lt;a href="https://aka.ms/helloworld"&gt;Hello World show page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This week we meet Tasha Scott, a Business Program Manager based in Seattle WA.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/TashasEv"&gt;Tasha on Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.linkedin.com/in/tasha-scott-bb74b245/"&gt;Tasha on LinkedIn&lt;/a&gt;
&lt;a href="https://channel9.msdn.com/Shows/Hello-World/Hello-World-Thursday-March-11-2021#time=10m23s"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RLil9TXN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://humansofmsftstore.blob.core.windows.net/thumbnails/Humans-of-MSFT-S01E02-Tasha-Scott-Player.png" alt="Play the video"&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Laurent: Welcome to humans of Microsoft. This is a segment where we meet people just like you and me, but they have one thing in common. They all work for Microsoft and today I'm joined by Tasha Scott. Hello Tasha, how are you?&lt;/p&gt;

&lt;p&gt;Tasha: Hi, I'm doing great. How are you Laurent?&lt;/p&gt;

&lt;p&gt;Laurent: I'm very good. Thank you. And Tasha, you are a business program manager and you are based in Seattle, very close to Microsoft Headquarters, right?&lt;/p&gt;

&lt;p&gt;Tasha: Yes, Yep, beautiful lovely, great day here in Seattle as one would expect. It's not really cold&lt;/p&gt;

&lt;p&gt;Laurent: Cool, so let's go into the questions. So the first question is what was a key moment, a pivotal moment in your career.&lt;/p&gt;

&lt;p&gt;Tasha: So a pivotal moment in my career was when I actually got my first mentor and that's what really started my career in tech. I joined a user group. My first user group and the the woman who ran the user group became my mentor and if it wasn't for her, I wouldn't be here today. She was an incredible mentor for me and made sure that I was set up for success.&lt;/p&gt;

&lt;p&gt;Laurent: Oh, that's fantastic and really mentors and mentoring people and getting a mentor is very important for careers in tech, right?&lt;/p&gt;

&lt;p&gt;Tasha: Absolutely 100%.&lt;/p&gt;

&lt;p&gt;Laurent: Yeah, I completely agree. So then if you could go back in time and find yourself like years before now. What would you tell yourself to help you getting started?&lt;/p&gt;

&lt;p&gt;Tasha: Uh, so I started out, uhm, I don't, I'm not a typical tech career path person and so the thing that I would tell myself is I would, I would say like hey, a career in tech is possible for you and just so I could get started earlier. I never pictured myself having a career in tech and so I I just never, like, it wasn't something that I considered and so I didn't really pursue it. And I really wish that I could go back in time and just tell myself, hey this is a thing that's possible for you and you know, here's how you can, here's how you can do that. And I I would, you know, get started earlier if I could.&lt;/p&gt;

&lt;p&gt;Laurent: Yeah, that's really interesting. And and that kind of brings me to the next question, which is do you even need a computer science degree to work at Microsoft?&lt;/p&gt;

&lt;p&gt;Tasha: Absolutely not, and I am proof positive of that, so I don't have a computer science degree. My degree is actually in English, and before my tech career, I worked at a newspaper for a bunch of years.&lt;/p&gt;

&lt;p&gt;Laurent: Yes, and we in fact have a lot of roles at Microsoft, so it's not just developers and programmers and we have a lot of developers who aren't computer science, you know?&lt;/p&gt;

&lt;p&gt;Tasha: Yeah and I'm still in a technical role. I'm a citizen developer inside Microsoft, building programs for our sales operations worldwide.&lt;/p&gt;

&lt;p&gt;Laurent: Fantastic, what would you say has been the key to the success in your career in tech?&lt;/p&gt;

&lt;p&gt;Tasha: Uh, absolutely community. 100% tech communities are really the way to learn anything that you want to learn in tech. Whatever your chosen stack is, go find the community that that you know that stack belongs to and join that community. Participate in that community and you'll get so much support and you will learn so much through your community. It's really 100% the best way to get started and find success in your tech career.&lt;/p&gt;

&lt;p&gt;Laurent: I cannot agree more. This is also how I got started and what brought me eventually to Microsoft. The last question I have. What is one more thing you want to tell to all our viewers to inspire them?&lt;/p&gt;

&lt;p&gt;Tasha: I just I really like for all the people out there that think to themselves that maybe a tech career is out of reach or you just don't think you belong there or you think that you you couldn't make it. You really do have something to offer and it is something that you you can have if that's what you choose to do, there's there's nothing keeping you from having a tech career you absolutely can. You can come, you can work at Microsoft, which if you had told me, you know however many years ago, that one day you'd be working at Microsoft, I would have told you that was bananas, but it's not bananas. You should absolutely try if it's something that you want to do and find that tech community, find a mentor and you will make it. I believe in you&lt;/p&gt;

&lt;p&gt;Laurent: Fantastic message. Well, thank you so much Tasha. It's been awesome talking to you and thank you to all our viewers for watching and we'll see you next time on another Humans of Microsoft. Thanks Tasha.&lt;/p&gt;

&lt;p&gt;Tasha: Thank you. Have a great day.&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>humansofmicrosoft</category>
      <category>helloworld</category>
    </item>
    <item>
      <title>Humans of Microsoft S01E01: LaBrina Loving</title>
      <dc:creator>Laurent Bugnion</dc:creator>
      <pubDate>Thu, 24 Jun 2021 14:40:48 +0000</pubDate>
      <link>https://forem.com/azure/humans-of-microsoft-s01e01-labrina-loving-1oam</link>
      <guid>https://forem.com/azure/humans-of-microsoft-s01e01-labrina-loving-1oam</guid>
      <description>&lt;p&gt;Humans of Microsoft is not about tech, it's about humans just like you and me, but they all work for Microsoft. Discover a new guest every week in this series, either live on &lt;a href="https://aka.ms/learntv"&gt;Learn TV&lt;/a&gt; or on the &lt;a href="https://aka.ms/helloworld"&gt;Hello World show page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This week we meet LaBrina Loving, a Principal Program Manager based in Washington DC.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/chixcancode"&gt;LaBrina on Twitter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/chixcancode/"&gt;LaBrina on LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://channel9.msdn.com/Shows/Hello-World/Hello-World-Thursday-4-March-2021#time=13m55s"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xTl62Bqj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://humansofmsftstore.blob.core.windows.net/thumbnails/Humans-of-MSFT-S01E01-LaBrina-Loving-Player.png" alt="Play the video"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Transcript
&lt;/h2&gt;

&lt;p&gt;Laurent: Welcome to Humans of Microsoft. This is a segment where we talk to people just like you and me, but they have one thing in common: They all work for Microsoft. Today I'm joined by LaBrina Loving. Hello LaBrina, how are you doing?&lt;/p&gt;

&lt;p&gt;LaBrina: Hi, how are you?&lt;/p&gt;

&lt;p&gt;Laurent: I'm very good, thank you. LaBrina, You are a senior custom engineer and you are based in Washington DC right?&lt;/p&gt;

&lt;p&gt;LaBrina: That is correct, yes.&lt;/p&gt;

&lt;p&gt;Laurent: Awesome. So let's go straight into the questions. What would you say was a key moment in your career, like a pivotal moment? If you think back.&lt;/p&gt;

&lt;p&gt;LaBrina: Yes, I would say my very first job in tech was critical. I started in an organization, I didn't know anything that was going on. They had this architecture diagram with all these technologies that I wasn't familiar with and it was really intimidating. But what I did was, I spent several, several weeks really learning, really researching. And I think it sort of changed my career and showed me that I could really do this thin in tech.&lt;/p&gt;

&lt;p&gt;Laurent: Oh, that's amazing. And definitely you never stop learning in this profession, right?&lt;/p&gt;

&lt;p&gt;LaBrina: For sure.&lt;/p&gt;

&lt;p&gt;Laurent: Yeah, that's really cool. If you could go back in time like anytime you want and see yourself as a younger person, you are obviously still young and all but younger, what would you tell yourself to help you getting started?&lt;/p&gt;

&lt;p&gt;LaBrina: Yeah, I would say don't be intimidated. Don't be afraid to go and go after what you want, even if it means that there's no one that looks like you at the beginning. If it's something that you want totally go after it.&lt;/p&gt;

&lt;p&gt;Laurent: Wow, yeah, that's a that's great advice, most probably right? You are very passionate about science, technology, engineering and math, which we commonly abbreviated as STEM, right? And so can you share some of the work that you're doing in this area?&lt;/p&gt;

&lt;p&gt;LaBrina: Yeah, so one of the cool things I'm working on right now is with our employee resource group Blacks @ Microsoft. We're working in conjunction with a college here in the Washington DC area. And a group of middle school students where we're actually teaching them STEM. Right now, we're teaching them how to code in Python. And the Microsoft employees are putting together their curriculum. Our college students are delivering the curriculum and middle school students are learning, so we've got learning going at three levels, and it's amazing.&lt;/p&gt;

&lt;p&gt;Laurent: Oh yes, that sounds amazing, because learning to teach is also very important, right?&lt;/p&gt;

&lt;p&gt;LaBrina: Right, correct.&lt;/p&gt;

&lt;p&gt;Laurent: Oh, that sounds really great. And so in your free time, and when it's allowed, I hear you're really the world traveler, just like me, right? So what would you say was your most exciting adventure?&lt;/p&gt;

&lt;p&gt;LaBrina: Yeah, so I love to travel. I've been to 39 countries so far, but one of the things that I like to do is something where I go very last minute. So actually I was working with a customer here at Microsoft. I had a weekend to myself. I just went to the airport, looked for flights that were departing in the next two hours, and I hopped on a plane. At that point it actually ended up being, I flew to Barcelona for the weekend right. But yeah, I like the idea of just being very spontaneous and traveling somewhere I've never been to, very last minute.&lt;/p&gt;

&lt;p&gt;Laurent: Yeah, this is very exciting indeed.  did something similar at some point within the US, but it was really cool. So one more question. What is one more thing that you would tell our viewers, to try to inspire them and motivate them?&lt;/p&gt;

&lt;p&gt;LaBrina: Yeah, I would say just don't, don't be afraid. I think fear really creeps into everything that we do. I would say don't be afraid to jump in tech and don't be afraid to learn out loud and ask questions. And and you know, ask for help like I, I think I cannot say that enough, that it's really, really important to get comfortable with asking for help and learning out loud.&lt;/p&gt;

&lt;p&gt;Laurent: Yeah, I see I think it's true, and in fact mentoring and being mentored is very important in someone's carrier, right?&lt;/p&gt;

&lt;p&gt;LaBrina: Yes, absolutely.&lt;/p&gt;

&lt;p&gt;Laurent: Perfect. Well, this has been fantastic talking to you. So thank you so much for being with us today, LaBrina, and to all of our viewers, come next time and join us for another Humans of Microsoft. Thank you.&lt;/p&gt;

&lt;p&gt;LaBrina: Thank you.&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>humansofmicrosoft</category>
      <category>helloworld</category>
    </item>
    <item>
      <title>Best practice when naming Durable Functions in C#</title>
      <dc:creator>Laurent Bugnion</dc:creator>
      <pubDate>Wed, 04 Nov 2020 19:37:03 +0000</pubDate>
      <link>https://forem.com/azure/best-practice-when-naming-durable-functions-in-c-2i0o</link>
      <guid>https://forem.com/azure/best-practice-when-naming-durable-functions-in-c-2i0o</guid>
      <description>&lt;p&gt;When you create a new &lt;a href="http://gslb.ch/d597b"&gt;Durable Function in C#&lt;/a&gt;, you get some code which looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;FunctionName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Function1"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;RunOrchestrator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;OrchestrationTrigger&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;IDurableOrchestrationContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;outputs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Replace "hello" with the name of your Durable Activity Function.&lt;/span&gt;
    &lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CallActivityAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"Function1_Hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Tokyo"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CallActivityAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"Function1_Hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Seattle"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CallActivityAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"Function1_Hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"London"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;FunctionName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Function1_Hello"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;SayHello&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;ActivityTrigger&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Saying hello to &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;$"Hello &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;For brevity, I didn't include the HttpStart method here, it's not relevant to this discussion.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you can see here, the execution of the program relies on some strings. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;FunctionName&lt;/code&gt; attribute which decorates the function &lt;code&gt;SayHello&lt;/code&gt; uses a string as the function's identifier.&lt;/li&gt;
&lt;li&gt;When the function is called by the &lt;code&gt;context.CallActivityAsync&lt;/code&gt; method, the first argument of the method is the magic string identifying the function.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  About Magic strings
&lt;/h2&gt;

&lt;p&gt;The term "Magic string" in programming refers to identifiers which are stored in a string format. They are deemed "magic" because they have a specific meaning critical to the execution of the program.&lt;/p&gt;

&lt;p&gt;One thing I learned when I was learning programming is that in general, it's not a great idea to rely on "magic strings". They are dangerous, because a typo will not be detected by the compiler (compilers don't normally check the format of string variables). So the risk of getting problems at some point is higher.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the &lt;code&gt;nameof&lt;/code&gt; operator
&lt;/h2&gt;

&lt;p&gt;In order to minimize the need of magic string, C# introduced the &lt;code&gt;nameof&lt;/code&gt; operator.&lt;/p&gt;

&lt;p&gt;This can be used on a number of identifiers in the code. For example you can consider this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;MyProperty&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;MyMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ShowNames&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyClass&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// prints "MyClass"&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyProperty&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// prints "MyProperty"&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyMethod&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// prints "MyMethod"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  So what's the point?
&lt;/h2&gt;

&lt;p&gt;The point of the &lt;code&gt;nameof&lt;/code&gt; operator is that it makes it easier to detect typos or changes in the code. For example, if you change the name of &lt;code&gt;MyClass&lt;/code&gt; to &lt;code&gt;MyNewClass&lt;/code&gt;, then the code won't compile unless you also change it inside the &lt;code&gt;nameof&lt;/code&gt; operator.&lt;/p&gt;

&lt;p&gt;If you use refactoring tools, for example inside of Visual Studio, you can easily rename all the instances of the &lt;code&gt;MyClass&lt;/code&gt; identifier without having to search-and-replace.&lt;/p&gt;

&lt;p&gt;Finally, it also makes it easier to navigate the code. If you are inside the &lt;code&gt;nameof&lt;/code&gt; operator, place your cursor on &lt;code&gt;MyClass&lt;/code&gt; and press F12 (in Visual Studio), this will take you directly inside the &lt;code&gt;MyClass&lt;/code&gt; class, even if it is located in another file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps for Durable Functions
&lt;/h2&gt;

&lt;p&gt;For Durable Functions, my first step was always to modify the code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;FunctionName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Function1&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;RunOrchestrator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;OrchestrationTrigger&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;IDurableOrchestrationContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;outputs&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Replace "hello" with the name of your Durable Activity Function.&lt;/span&gt;
    &lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CallActivityAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SayHello&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"Tokyo"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CallActivityAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SayHello&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"Seattle"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CallActivityAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SayHello&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"London"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;FunctionName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SayHello&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;SayHello&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;ActivityTrigger&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Saying hello to &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;$"Hello &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These few changes (using &lt;code&gt;nameof&lt;/code&gt;) minimize the usage of magic strings and make it easier for me to navigate the code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changing the templates
&lt;/h2&gt;

&lt;p&gt;In order to make this easier for everyone, I proposed &lt;a href="https://github.com/Azure/azure-functions-templates/pull/993"&gt;a change to the C# templates for Durable Functions&lt;/a&gt; which, if accepted, should promote the usage of &lt;code&gt;nameof&lt;/code&gt; in the generated code.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;Laurent&lt;/p&gt;

</description>
      <category>serverless</category>
      <category>azurefunctions</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>Microsoft Ignite 2020</title>
      <dc:creator>Laurent Bugnion</dc:creator>
      <pubDate>Tue, 22 Sep 2020 12:04:52 +0000</pubDate>
      <link>https://forem.com/lbugnion/microsoft-ignite-2020-5aoh</link>
      <guid>https://forem.com/lbugnion/microsoft-ignite-2020-5aoh</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--i-DeiQt6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/tJwt2zR.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i-DeiQt6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/tJwt2zR.png" alt="Microsoft Ignite 2020"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This week (in fact, today) we are starting &lt;a href="http://gslb.ch/d408b"&gt;Microsoft Ignite&lt;/a&gt;, our biggest conference of the year. It is the first time that we have to run the event online, which of course is a bit sad (last year's event in Orlando was amazing, so many people...) but in the other hand it's also the chance for everyone to see the event LIVE and to ask questions from the experts in real time. We'll have 3 days of content non stop (yes literally 24/7) around the globe. Exciting!&lt;/p&gt;

&lt;p&gt;I'll be doing a lot of moderation and Q&amp;amp;A behind the scenes so if you see me in the chat, be sure to say hi. But even better I'll also have two "on-stage" appearances, so mark your calendars and add me to your schedule or your backpack.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="http://gslb.ch/d574b"&gt;Migrating an ASP.NET web application to Azure App Service&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ekWyhftB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/5P4SAXw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ekWyhftB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/5P4SAXw.png" alt="Migrating an ASP.NET web application to Azure App Service"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.timeanddate.com/worldclock/fixedtime.html?msg=Ignite+20%3A+Migrating+an+ASP.NET+web+application+to+Azure+App+Service&amp;amp;iso=20200923T14&amp;amp;p1=268&amp;amp;am=15"&gt;Date / Time: September 23, 2020 at 2PM CEST&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Azure App Services offer a wide range of platforms, functionalities, and utilities around your web application. In this session, we will see how an ASP.NET web application can be migrated from a local environment to Azure with the help of our tools and processes. We will also talk about the configuration of the App Service, such as improving security, automatically scaling and more.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;During this &lt;a href="http://gslb.ch/d574b"&gt;15 minutes interstitial program&lt;/a&gt;, I will join Seth Juarez and Christina Warren to talk about ways to migrate ASP.NET applications to Azure App Service, advantages, tools etc. We will also see a demo migrating an old ASP.NET WebForms app (.NET 3.5) to &lt;a href="http://gslb.ch/d575b"&gt;Azure App Service&lt;/a&gt; with almost no changes, and how to improve the configuration by using &lt;a href="http://gslb.ch/d576b"&gt;Azure Key Vault&lt;/a&gt; for the secrets (such as a configuration string).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that there is no repeat for this short session, but it will be recorded.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Exploring core concepts in Azure Data
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dNNUORrp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/QdjcTYg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dNNUORrp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/QdjcTYg.png" alt="Exploring core concepts in Azure Data"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.timeanddate.com/worldclock/fixedtime.html?msg=Exploring+core+concepts+in+Azure+Data&amp;amp;iso=20200924T14&amp;amp;p1=268&amp;amp;ah=1&amp;amp;am=15"&gt;Date / Time: September 24, 2020 at 2PM CEST&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Microsoft Learn Workshops are designed to be interactive and hands on. For the most immersive experience we recommend the prerequisites suggested in the module link provided below but are not required to join. To ensure everyone attending has the best involvement, these sessions have limited capacity. But don't worry, they are being recorded and will be available on demand.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Join us for this guided online Microsoft Learn workshop: &lt;a href="https://aka.ms/Learn/AzureDataConcepts"&gt;https://aka.ms/Learn/AzureDataConcepts&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This 75 minutes workshop will take place 3 times, and this is the 3rd repeat. Join me to go through a series of Microsoft Learn Module and slides teaching you the fundamentals of data on Azure. This is great for beginners!! We will talk about relational databases (&lt;a href="http://gslb.ch/d577b"&gt;such as Azure SQL Database&lt;/a&gt;, &lt;a href="http://gslb.ch/d578b"&gt;Azure SQL Database Managed Instance&lt;/a&gt;), semi-structured databases &lt;a href="http://gslb.ch/d7b"&gt;such as CosmosDB&lt;/a&gt;, big data and more.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that you need to register for this event! Places are limited.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I am really looking forward to this event, and hopefully I will reach out to a lot of you.&lt;/p&gt;

&lt;p&gt;Stay safe!&lt;/p&gt;

&lt;p&gt;Laurent&lt;/p&gt;

</description>
      <category>microsoftignite</category>
      <category>azuresql</category>
      <category>aspnet</category>
      <category>appservice</category>
    </item>
    <item>
      <title>Notifications Client Step 1.0: Creating the FCM project</title>
      <dc:creator>Laurent Bugnion</dc:creator>
      <pubDate>Thu, 09 Jul 2020 13:21:30 +0000</pubDate>
      <link>https://forem.com/azure/notifications-client-step-1-0-creating-the-fcm-project-4f3a</link>
      <guid>https://forem.com/azure/notifications-client-step-1-0-creating-the-fcm-project-4f3a</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FUdszogi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FUdszogi.png" alt="Xamarin, Notification Hub, Functions, Cosmos DB"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ZliwX9Hgy0c"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/lbugnion/sample-azure-xamarin-notifications" rel="noopener noreferrer"&gt;Find the GitHub repository for this series here&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://dev.to/azure/notifications-client-step-0-specification-527p"&gt;Previous article: Notifications Client Step 0: Specification&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/azure/building-a-notifications-client-with-xamarin-and-azure-p6e"&gt;Main article: Building a notifications client with Xamarin and Azure&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have decided to build a cross-platform Notifications Client used to receive push notifications when a long-running system needs it. This Notifications Client is generic, and not tied to a specific system or application, but serves as a receiver and repository for all kinds of notifications.&lt;/p&gt;

&lt;p&gt;This article is part of a series. In here, we will set the Firebase Cloud Messaging (FCM) service and prepare it to be an intermediate between Azure Notification Hub and our mobile app on Android.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a new FCM project
&lt;/h2&gt;

&lt;p&gt;Android notifications are sent through a service called Firebase Cloud Messaging (this is a Google service). When you use an "aggregation service" like Azure Notification Hub, this service will communicate with FCM to send the notification to all the Android devices who registered for it. Similarly, Notification Hub will also communicate with corresponding services for Windows (we will set this later) and for iOS.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: For this to work, the Android device needs to support Google Play Services. The Azure Notification Hub also supports Baidu as a target, but this won't be treated in this article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To start, we need to &lt;a href="https://console.firebase.google.com/" rel="noopener noreferrer"&gt;navigate to the Firebase console&lt;/a&gt;. Then follow the steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on Create a project.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F01TFEB0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F01TFEB0.png" alt="Creating a new Firebase project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the first step, enter a name for your new project. You can choose any name, this is just for management purposes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Frs58ca8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Frs58ca8.png" alt="Setting up the new Firebase project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can choose to enable analytics or not. In my case, I decided to turn this off, because I will be using Application Insights on Azure to monitor the system, and I don't really need a separate analytics solution just for the Android devices. But your mileage may vary...&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FU6GJUF7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FU6GJUF7.png" alt="Setting up the project's analytics"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The new project will be provisioned, so just wait for a moment until it is ready.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FJBtqV93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FJBtqV93.png" alt="Provisioning..."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Firebase can be used for quite a lot of things next to push notifications, but we are not going to use these features here. The main point of this project is to be a gateway between Azure Notification Hub and the Android devices.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Now we will configure the Android application. This is quite easy. First, in the "Get started by adding Firebase to your app" section, click on the Android icon.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FC4DZ8dY.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FC4DZ8dY.png" alt="Starting the Android configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Next, we will link the Firebase project to the Android application that we will create later. You need to enter an Android package name. You can also enter a nickname for this app, this is just for management purpose.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;The Android package name is of the form &lt;code&gt;com.[yourcompanyname].[yourapplicationname]&lt;/code&gt;. Make sure to write it down for later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FlDdKwLY.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FlDdKwLY.png" alt="Setting up the application's details"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On the next step, download the &lt;code&gt;google-service.json&lt;/code&gt; file and save it in a safe location. This file contains all the information needed by the Android devices to register with the Firebase system to get the notifications.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FTw4q1LE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FTw4q1LE.png" alt="Downloading the configuration file"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On the next screen, you can just press &lt;code&gt;Next&lt;/code&gt; and then &lt;code&gt;Continue to console&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fk4YLv1V.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fk4YLv1V.png" alt="Skipping to the next step"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing down the keys
&lt;/h2&gt;

&lt;p&gt;Now we will write down the secret keys that we'll need to use in the Android application. Later we'll use these keys in the Xamarin code, and even later we'll save these keys to Azure Key Vault for safe keeping.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In the Firebase Console, select your application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the application dashboard, click on the button with the small Android icon, and the name of your app.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FjUUUVlJ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FjUUUVlJ.png" alt="Navigating to your application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the Settings icon&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FpVp4MHT.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FpVp4MHT.png" alt="Navigating to the settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on &lt;code&gt;Cloud Messaging&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FSalMji7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FSalMji7.png" alt="Navigating to Cloud Messaging"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy the Server Key and save it somewhere for later.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FYHwMa6t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FYHwMa6t.png" alt="Copying the Server Key"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Well done!!
&lt;/h2&gt;

&lt;p&gt;That's it, you have created and configured a new Google Firebase Cloud Messaging project, and downloaded the file you need.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you lose the &lt;code&gt;google-services.json&lt;/code&gt; file, you can always retrieve it &lt;a href="https://console.firebase.google.com/" rel="noopener noreferrer"&gt;from the Firebase console&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You have also retrieved the Server key which we will use to configure the Azure Notification Hub. Make sure to save it!&lt;/p&gt;

&lt;h2&gt;
  
  
  In the next article...
&lt;/h2&gt;

&lt;p&gt;In the next article (coming soon), we will see how to build an "empty" Xamarin Forms application and configure it to receive the notification from FCM.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/lbugnion/sample-azure-xamarin-notifications" rel="noopener noreferrer"&gt;Find the GitHub repository for this series here&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://dev.to/azure/building-a-notifications-client-with-xamarin-and-azure-p6e"&gt;Main article: Building a notifications client with Xamarin and Azure&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;Laurent&lt;/p&gt;

</description>
      <category>azure</category>
      <category>notificationhub</category>
      <category>xamarin</category>
    </item>
    <item>
      <title>Notifications Client Step 0: Specification</title>
      <dc:creator>Laurent Bugnion</dc:creator>
      <pubDate>Mon, 22 Jun 2020 16:32:22 +0000</pubDate>
      <link>https://forem.com/azure/notifications-client-step-0-specification-527p</link>
      <guid>https://forem.com/azure/notifications-client-step-0-specification-527p</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CQX_i7p1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/Udszogi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CQX_i7p1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/Udszogi.png" alt="Xamarin, Notification Hub, Functions, Cosmos DB"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ZliwX9Hgy0c"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/lbugnion/sample-azure-xamarin-notifications"&gt;Find the GitHub repository for this series here&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://dev.to/azure/building-a-notifications-client-with-xamarin-and-azure-p6e"&gt;Main article: Building a notifications client with Xamarin and Azure&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have decided to build a cross-platform Notifications Client used to receive push notifications when a long-running system needs it. This Notifications Client is generic, and not tied to a specific system or application, but serves as a receiver and repository for all kinds of notifications.&lt;/p&gt;

&lt;p&gt;I have the following specifications in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The client will have different pages. The notifications can have a "channel", which will sort them to a specific page.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: The "channel" here is a custom property I am adding to the notification for my own purpose. It's not the same at the Push Notification Topic in Firebase, which allows to push notifications only to selected devices, or the customer segments in Windows, which have the same goal. Here we just use the channel as a way to sort notifications in pages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7i8xmRcs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/VgEF7yZ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7i8xmRcs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/VgEF7yZ.png" alt="App main page with all the channels"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;App main page with all the channels&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There should be one page showing all the notifications, and one page per channel with only the corresponding notifications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tqppLIei--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/ltjgQbb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tqppLIei--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/ltjgQbb.png" alt="Channel page with the corresponding notifications"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Channel page with the corresponding notifications&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8QXkbAtc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/hQSxBSb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8QXkbAtc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/hQSxBSb.png" alt="Detail of a notification template"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Detail of a notification template&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The client should save the notifications locally.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The client should allow the notifications to be searched on the current page (or the "all notifications" page).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Notifications can be received when the application is off, or when it is running.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Eventually, the notifications should also be saved in the app for offline mode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Notifications can be deleted from the app.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RRayjrX8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/XbETnSJ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RRayjrX8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/XbETnSJ.png" alt="Detail page for a notification"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Detail page for a notification&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The client should be implemented in &lt;a href="http://gslb.ch/d424b"&gt;Xamarin.Forms&lt;/a&gt; to be cross-platform, even though initially I only need Android and possibly Windows (UWP).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;The architecture is composed of a few Azure services, as well as a Google service for Android notifications, a Windows service for Windows notifications, and later of an Apple service for iOS notifications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e1nktPhR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/cPGS4vU.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e1nktPhR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/cPGS4vU.png" alt="Notification system architecture"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Notification system architecture&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Any system can send a simple POST request over HTTP to an &lt;a href="http://gslb.ch/d10b"&gt;Azure Functions endpoint&lt;/a&gt;. The payload is a simple JSON file containing a title, a message and an optional channel.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;If you are watching systems on Azure, a great way to connect a system to the Azure Functions endpoint &lt;a href="http://gslb.ch/d430b"&gt;is to use EventGrid&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The Azure Function passes the notification request to an &lt;a href="http://gslb.ch/d425b"&gt;Azure Notification Hub&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Notification Hub communicates with &lt;a href="http://gslb.ch/d426b"&gt;Firebase Cloud Messaging (FCM)&lt;/a&gt; (Android), the corresponding services for Windows (&lt;a href="http://gslb.ch/d427b"&gt;Windows Push Notification Service WNS&lt;/a&gt;) and iOS (&lt;a href="http://gslb.ch/d428b"&gt;Apple Push Notification Service APNS&lt;/a&gt;). The notification is enqueued on these systems and sent to registered devices.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Azure Notification Hub also supports other systems such as Amazon (ADM), Baidu, and even good old Windows Phone!!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;FCM sends the notification to registered Android devices. Similarly, APNS sends the notification to iOS devices, and WNS sends the notification to Windows devices. What happens on the device is described below in When a device receives a notification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After the push notification has been successfully enqueued, it is saved to a cloud database. We will use the &lt;a href="http://gslb.ch/d422b"&gt;new CosmosDB free tier for this&lt;/a&gt;, as this allows for a powerful yet simple NoQSL database to be used.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a id="NotificationOnDevice"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  When a device receives a notification
&lt;/h2&gt;

&lt;p&gt;There are three scenarios. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The application is running in the foreground&lt;/strong&gt;: The new notification is shown on a page, the user's attention is attracted for example by a sound or a flashing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The application is in the background, or not running&lt;/strong&gt;: The new notification is displayed as a push notification. The user taps the notification, which starts the app. The new notification is shown on a page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Same scenario but the user dismisses the notification&lt;/strong&gt;: Nothing happens until the next time that the app starts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When the running app receives a new notification, or when the app is started from a new notification, the notification is saved in a local database on the device (&lt;a href="http://gslb.ch/d429b"&gt;SQLite&lt;/a&gt;). &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A synchronization can occur between the cloud database and the device database. The synchronization is started by the user, it also occurs when a notification is deleted on a device, or every time that the application starts.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  In the next article...
&lt;/h2&gt;

&lt;p&gt;Hopefully these specs make sense for everyone! &lt;/p&gt;

&lt;p&gt;In the next article, we will get started with the implementation of the notification system!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/lbugnion/sample-azure-xamarin-notifications"&gt;Find the GitHub repository for this series here&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://dev.to/azure/building-a-notifications-client-with-xamarin-and-azure-p6e"&gt;Main article: Building a notifications client with Xamarin and Azure&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/azure/notifications-client-step-1-0-creating-the-fcm-project-4f3a"&gt;Next article: Notifications Client Step 1.0: Creating the FCM project&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy coding&lt;/p&gt;

&lt;p&gt;Laurent&lt;/p&gt;

</description>
      <category>azure</category>
      <category>notificationhub</category>
      <category>xamarin</category>
    </item>
    <item>
      <title>Building a notifications client with Xamarin and Azure</title>
      <dc:creator>Laurent Bugnion</dc:creator>
      <pubDate>Wed, 17 Jun 2020 12:10:31 +0000</pubDate>
      <link>https://forem.com/azure/building-a-notifications-client-with-xamarin-and-azure-p6e</link>
      <guid>https://forem.com/azure/building-a-notifications-client-with-xamarin-and-azure-p6e</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ZliwX9Hgy0c"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/lbugnion/sample-azure-xamarin-notifications"&gt;Find the GitHub repository for this series here&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I often find myself needing to send a notification to my mobile device, for example when a job finishes on Azure, when one of my computers at home is done doing something, or when I just want to send an alert when something changes in a system I am observing. &lt;/p&gt;

&lt;p&gt;Normally I would go ahead and create a companion app for the system I am building, and then send notifications to this app, but sometimes it's really overkill to build a full-blown app for this. This is why I decided to build a generic notifications client that I can install on my phone.&lt;/p&gt;

&lt;p&gt;What's really cool is that a lot of the development (with dotnet and Xamarin) can be done locally on my Surface Pro, which makes testing and debugging very much easier, before the services and applications are deployed to Azure and to my devices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Push Notifications? (aka why not SignalR?)
&lt;/h2&gt;

&lt;p&gt;Why did I choose to use push notifications and not another messaging service like SignalR for example?&lt;/p&gt;

&lt;p&gt;SignalR is an amazing feature that you can easily add to a Xamarin application &lt;a href="https://github.com/lbugnion/sample-xamarin-signalr"&gt;as shown in this sample&lt;/a&gt;. It is very well suited for high traffic, real-time communication. In our scenario, it doesn't quite fit, because we want the notifications to reach the device also when the application is not running, which is exactly what push notifications are made for. Also, even when the application is running, adding SignalR would be overkill because we don't really need real time, high traffic here. What we get from our watched systems is a notification from time to time, and even if this notification is delayed by a few seconds, it's not mission critical.&lt;/p&gt;

&lt;p&gt;Finally the push notification system also includes retries, in case one device is offline for a period of time. This is very useful for our scenario too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;p&gt;I am planning to build this system in the following order:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 0: Specification
&lt;/h3&gt;

&lt;p&gt;In this step we will specify what we want the system to achieve, create a few sketches of the application and get ready :)&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Sending a notification from the Firebase Cloud Messaging
&lt;/h3&gt;

&lt;p&gt;The first step will include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating a new project in Google Firebase and setting up &lt;a href="http://gslb.ch/d426b"&gt;Firebase Cloud Messaging (FCM)&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Building a client app just here to receive the Push Notification and test that it works.&lt;/li&gt;
&lt;li&gt;Test the notification with &lt;a href="https://www.postman.com/"&gt;with Postman&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Sending a notification from Azure Notification Hub](./building-notifications-client-2.md)
&lt;/h3&gt;

&lt;p&gt;So far I hadn't worked directly with &lt;a href="http://gslb.ch/d425b"&gt;Azure Notification Hub&lt;/a&gt; (I was using App Center, &lt;a href="http://gslb.ch/d423b"&gt;but this is being retired&lt;/a&gt;), so I need to figure out how the Notification Hub works. Thankfully there is good documentation available. Here is what we'll do in this step:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new Azure Notification Hub and connect it to FCM.&lt;/li&gt;
&lt;li&gt;Test the setup by sending a push notification &lt;a href="https://www.postman.com/"&gt;with Postman&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Build the endpoint and connect to Notification Hub.
&lt;/h3&gt;

&lt;p&gt;Once we have the FCM project and the Notification Hub set up, we can build an &lt;a href="http://gslb.ch/d10b"&gt;Azure Function&lt;/a&gt; to serve as the main endpoint for the notification system. The Azure Function will communicate with the Azure Notification Hub by means of an SDK for .NET. This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build the Azure Functions application locally.&lt;/li&gt;
&lt;li&gt;Build a test request in Postman to try things out.&lt;/li&gt;
&lt;li&gt;Create the Azure Functions application on Azure.&lt;/li&gt;
&lt;li&gt;Publish the function to the Azure Functions application.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Not started yet&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step: Sending a notification from the Windows Push Notification Services
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Not started yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step: Show the new notification in a page on the device.
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Not started yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step: Save the notifications in Cosmos DB.
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Not started yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step: Get the notifications from Cosmos DB into the app.
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Not started yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step: Save all the secrets to Azure KeyVault.
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Not started yet&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step: Organize the notifications in the app in pages.
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Not started yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step: Save the notifications locally (synchronize).
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Not started yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step: Customize the application with icons, design etc...
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Not started yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Building an ARM deployment template
&lt;/h2&gt;

&lt;p&gt;In order to allow people to use this on their own, I am also planning to prepare an ARM deployment template for the Azure components.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Azure Function connected to the Azure Functions application GitHub repo.&lt;/li&gt;
&lt;li&gt;CosmosDB.&lt;/li&gt;
&lt;li&gt;Notification Hub.&lt;/li&gt;
&lt;li&gt;KeyVault for the connection strings and other secrets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition I will write detailed description on how to create the Firebase Cloud Messaging project, and how to configure all the Azure pieces.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/lbugnion/sample-azure-xamarin-notifications"&gt;Find the GitHub repository for this series here&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://dev.to/azure/notifications-client-step-0-specification-527p"&gt;Next article: Notifications Client Step 0: Specification&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;Laurent&lt;/p&gt;

</description>
      <category>azure</category>
      <category>notificationhub</category>
      <category>xamarin</category>
    </item>
    <item>
      <title>Ethics in Artificial intelligence, a talk recorded in video</title>
      <dc:creator>Laurent Bugnion</dc:creator>
      <pubDate>Mon, 08 Jul 2019 15:15:39 +0000</pubDate>
      <link>https://forem.com/azure/ethics-in-artificial-intelligence-a-talk-recorded-in-video-bdm</link>
      <guid>https://forem.com/azure/ethics-in-artificial-intelligence-a-talk-recorded-in-video-bdm</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UC6W1rNZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/KrjODxZ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UC6W1rNZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/KrjODxZ.png" alt="Ethics in AI"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over the past few weeks, I was really happy to give a talk about a topic that has been preoccupying me for a long time, ever since I started reading science fiction and being confronted with the moral conflicts that advanced technology always brings to the front of the stage. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In order to get notified when more parts of this talk, as well as other talks that I am preparing, are published, &lt;a href="http://gslb.ch/d94b"&gt;please subscribe&lt;/a&gt; to my YouTube channel. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the talk, I mention a simple example: Imagine a self driving car who has to decide if it should go left and kill one human, or go right and kill 10 of us. Now imagine that the one person on the left is a child. How is a machine supposed to make this kind of decisions? Earlier this kind of moral question was only a theoretical one (see for instance &lt;a href="https://en.wikipedia.org/wiki/Three_Laws_of_Robotics"&gt;Isaac Asimov's laws of robotic&lt;/a&gt;). But now we need to think about these issues in a much more practical manner. We now have the data and the power to run artificial intelligence models, and we must deal with all kinds of ethical questions. &lt;/p&gt;

&lt;p&gt;The main issue we are dealing with these days is the bias in data. The talk explains in detail what bias is, and how it creeps into the AI models. We also talk about a few other ethical issues linked to AI, and explore some ways to improve the situation. Finally we end with a few positive examples where AI promotes inclusion and diversity, and shows that we should not abandon artificial intelligence, but that we should do our best to use it for the greater good. &lt;/p&gt;

&lt;p&gt;For the viewer's convenience, I split the 45 minutes talk in 7 parts which are between 3 and 7 minutes. I published parts 1 to 5 already and the rest will follow in the next few days. Hopefully this talk is useful for you! And if you like it, &lt;a href="http://gslb.ch/d94b"&gt;please subscribe to my YouTube channel&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Happy viewing! &lt;br&gt;
Laurent&lt;/p&gt;

</description>
      <category>ai</category>
      <category>ethics</category>
      <category>deeplearning</category>
    </item>
    <item>
      <title>DateTime.Now: No, no...</title>
      <dc:creator>Laurent Bugnion</dc:creator>
      <pubDate>Tue, 28 May 2019 11:47:03 +0000</pubDate>
      <link>https://forem.com/lbugnion/datetime-now-no-no-1013</link>
      <guid>https://forem.com/lbugnion/datetime-now-no-no-1013</guid>
      <description>&lt;p&gt;Recently my colleague and friend Donovan Brown was in Switzerland for customer visits and for &lt;a href="https://www.dotnetday.ch" rel="noopener noreferrer"&gt;the DotNet Day conference in Zurich&lt;/a&gt;. I took the occasion to spend some time with him and we got to talk (as you would expect) about geeky and "cloudy" stuff.&lt;/p&gt;

&lt;p&gt;One topic of discussion (and that was also mentioned by one of the clients) is: What do you need to get ready for the cloud... and one topic was: Timezones!!&lt;/p&gt;

&lt;h1&gt;
  
  
  What time is it, really?
&lt;/h1&gt;

&lt;p&gt;Because of all the regions we have, it means that your code suddenly has the potential to easily go global :) So here's a fun experiment you can do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a new web application. Here I use Visual Studio to create an &lt;a href="http://gslb.ch/d286b" rel="noopener noreferrer"&gt;ASP.NET Core web application with Razor pages&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the HTML code, display the local time and the UTC time. In ASP.NET, I can use the following code in the index.cshtml:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Local time: @DateTime.Now&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;UTC: @DateTime.UtcNow&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;In Razor pages, you can call C# code directly from the CSHTML markup, which is very convenient. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;Run the application locally. If like me you are based in Western Europe, you should see something like the below &lt;em&gt;(notice the 2 hours difference between local time and UTC)&lt;/em&gt;. If you are based somewhere else, it will vary, but there are very good chances that the Local time and the UTC time are going to be different (except of course if you happen to be in a timezone where the local time is the same as UTC).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3jyswhhuh32kz4jlune.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3jyswhhuh32kz4jlune.png" alt="Running the application locally" width="500" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Now deploy your application to Azure, into the West US region. You can do that from Visual Studio directly, or create an App Service in the &lt;a href="http://portal.azure.com" rel="noopener noreferrer"&gt;Azure Portal&lt;/a&gt; and deploy there.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the West US application. Now you should see the same time displayed for Local and for UTC.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wwi8ccoipa4tuuhs6ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wwi8ccoipa4tuuhs6ln.png" alt="Running the application in Azure" width="499" height="83"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;So that might be a surprise, and in fact I wasn't expecting that when I first did this experiment a few months ago. &lt;/p&gt;

&lt;p&gt;What's going on here is that the Azure architects decided to make it easy for people to migrate web applications (App Services) from region to region without changes in code used to calculate time and time differences. So they run all the Azure servers on UTC. On the other hand, this has the disadvantage that you might have to modify your code to take this in account when you migrate from on-premises to the cloud&lt;/p&gt;

&lt;p&gt;For example, if I am based in Switzerland and deploy my application to Western Europe (which is based in the Netherlands), I would expect my application to have the exact same &lt;code&gt;DateTime.Now&lt;/code&gt; in Azure than locally. And yet...&lt;/p&gt;

&lt;h1&gt;
  
  
  The morale of the story...
&lt;/h1&gt;

&lt;p&gt;The big learning here is that if you are looking to migrate to the cloud, suddenly timezones become very relevant, but not necessarily in the way that you would imagine. It's not that you need to &lt;strong&gt;know where your code will be running&lt;/strong&gt;. It is that you need to &lt;strong&gt;know that these regional questions will be abstracted&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;It would be a great idea to prepare yourself to the migration by doing the right thing already now on premises: Do not use &lt;code&gt;DateTime.Now&lt;/code&gt; in your code but use &lt;code&gt;DateTime.UtcNow&lt;/code&gt; instead and do the conversions where needed. This way you are already abstracting the location of your code, and when you migrate to the cloud and the location becomes irrelevant or unpredictable, your code will continue to work without being affected.&lt;/p&gt;

&lt;p&gt;Happy coding&lt;/p&gt;

&lt;p&gt;Laurent&lt;/p&gt;

</description>
      <category>datetime</category>
      <category>timezone</category>
      <category>migration</category>
    </item>
    <item>
      <title>Creating the simplest possible ASP.NET Core form with a POST method</title>
      <dc:creator>Laurent Bugnion</dc:creator>
      <pubDate>Mon, 04 Mar 2019 21:49:10 +0000</pubDate>
      <link>https://forem.com/azure/creating-the-simplest-possible-aspnet-core-form-with-a-post-method-416g</link>
      <guid>https://forem.com/azure/creating-the-simplest-possible-aspnet-core-form-with-a-post-method-416g</guid>
      <description>&lt;p&gt;Recently I needed to create a simple page for someone to submit an HTML form. The rest of the Azure aplication is running on &lt;a href="http://gslb.ch/d10b" rel="noopener noreferrer"&gt;Azure serverless functions&lt;/a&gt;, &lt;a href="http://gslb.ch/d266b" rel="noopener noreferrer"&gt;Logic apps&lt;/a&gt; and &lt;a href="http://gslb.ch/d117b" rel="noopener noreferrer"&gt;Cognitive services&lt;/a&gt;, but for that last part I wanted something where the user can click on a link, open the page in a web browser (probably on a mobile device), enter a passphrase in a form and the submit through a POST to an SSL encrypted page. I thought of writing a small Xamarin app and submitting through POST to an Azure Function. Another option would be to use a static HTML page and to use Javascript to submit the Form through a POST to that Azure Function. I don't exclude these two options for the future.&lt;/p&gt;

&lt;p&gt;But in the meantime I wanted to experiment with a simple &lt;a href="http://gslb.ch/d193b" rel="noopener noreferrer"&gt;Razor page (CSHTML)&lt;/a&gt; that would present an HTML Form to the user, and submit this Form to itself with a POST over HTTPS.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;a href="https://github.com/lbugnion/sample-dotnetcore-simplepostwithrazor/tree/master/src" rel="noopener noreferrer"&gt;source code for this example is here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Razor pages with models are really cool
&lt;/h2&gt;

&lt;p&gt;I love super simple &lt;a href="http://gslb.ch/d278b" rel="noopener noreferrer"&gt;ASP.NET Core&lt;/a&gt; sites without MVC. Don't get me wrong, &lt;a href="http://gslb.ch/d279b" rel="noopener noreferrer"&gt;MVC&lt;/a&gt; is awesome for enterprise web applications, where testability and maintainability are primordial. But they also come with a lot of overhead. If you go ahead and create an "empty" ASP.NET Core MVC website with the red-circled template below, you will end up with a lot of files (CSHTML pages, controllers, setup classes, Javascript, CSS etc). Even an empty ASP.NET Core MVC website contains 38 files (!).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fabviajehg8sljv0bwyd3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fabviajehg8sljv0bwyd3.png" alt="ASP.NET Core Razor and ASP.NET Core MVC templates in Visual Studio"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;ASP.NET Core Razor and ASP.NET Core MVC templates in Visual Studio&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Another option is to create an ASP.NET Core web application with Razor pages only. In such an app, you eliminate the controllers, and you handle the code in a &lt;a href="http://gslb.ch/d280b" rel="noopener noreferrer"&gt;PageModel&lt;/a&gt; instance which is attached to the CSHTML Razor page. This is definitely less complex and in fact my private website is implemented in this manner. However even if you create an "empty" web application in this manner using the orange-circled template shown above, you still end up with a lot of files and need to delete most of them. That's annoying and I prefer to start from a "truly empty" template like the one selected in blue in the image above.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Even though I use Visual Studio in this example, you can create the ASP.NET Core apps using a command line with the &lt;code&gt;dotnet new&lt;/code&gt; &lt;a href="http://gslb.ch/d281b" rel="noopener noreferrer"&gt;syntax shown here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Starting from scratch
&lt;/h2&gt;

&lt;p&gt;Let's start from scratch using the &lt;code&gt;Empty&lt;/code&gt; web app template shown above. To do this, in Visual Studio 2017, start by selecting File, New, Project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Before you start, you must make sure to have installed the .NET Core workload in the &lt;a href="http://gslb.ch/d282b" rel="noopener noreferrer"&gt;Visual Studio installer&lt;/a&gt;. You can always run the Visual Studio Installer from your Start menu, and check that the following workload is checked.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;&lt;em&gt;.NET Core workload&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the next step, you will have to select the Empty web application as shown below. You can enable HTTPS by default, which is usually a good idea. In our example we won't use authentication so you can leave this option to &lt;code&gt;No Authentication&lt;/code&gt;. Then click OK.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fabviajehg8sljv0bwyd3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fabviajehg8sljv0bwyd3.png" alt="Creating an empty ASP.NET Core application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Razor pages
&lt;/h2&gt;

&lt;p&gt;As the next steps, we will configure the application to serve Razor pages. To do this, and even though we are not going to use the full MVC capabilities here, we still need to ask the application to use MVC services.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;a href="https://github.com/lbugnion/sample-dotnetcore-simplepostwithrazor/blob/master/src/TestPostWithRazor/Startup.cs" rel="noopener noreferrer"&gt;Startup.cs&lt;/a&gt; in Visual Studio.&lt;/li&gt;
&lt;li&gt;Modify the &lt;code&gt;ConfigureServices&lt;/code&gt; method as follows:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConfigureServices&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IServiceCollection&lt;/span&gt; &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddMvc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Modify the &lt;code&gt;Configure&lt;/code&gt; method as shown below:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;IApplicationBuilder&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;IHostingEnvironment&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsDevelopment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseDeveloperExceptionPage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseMvc&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  Creating the Razor page
&lt;/h2&gt;

&lt;p&gt;With this configuration, the application will look for Razor (CSHTML) pages in a folder named &lt;code&gt;Pages&lt;/code&gt; and will direct the request to the page corresponding to the route (URL). In this example, since we want to keep it as simple as possible, we will use the default route and create a page named &lt;a href="https://github.com/lbugnion/sample-dotnetcore-simplepostwithrazor/blob/master/src/TestPostWithRazor/Pages/Index.cshtml" rel="noopener noreferrer"&gt;Index.cshtml&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Right click on the project and select &lt;code&gt;Add&lt;/code&gt; and then &lt;code&gt;New Folder&lt;/code&gt; from the context menu.&lt;/li&gt;
&lt;li&gt;Name this new folder &lt;code&gt;Pages&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Right click on the &lt;code&gt;Pages&lt;/code&gt; folder and select &lt;code&gt;Add&lt;/code&gt; and then &lt;code&gt;Razor Page&lt;/code&gt; from the context menu.&lt;/li&gt;
&lt;li&gt;in the &lt;code&gt;Add scaffold&lt;/code&gt; dialog, press on &lt;code&gt;Add&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;In the &lt;code&gt;Add Razor Page&lt;/code&gt; dialog, enter the name &lt;code&gt;Index&lt;/code&gt; and make sure that &lt;code&gt;Generate PageModel class&lt;/code&gt; is selected. &lt;/li&gt;
&lt;li&gt;Uncheck &lt;code&gt;Use a layout page&lt;/code&gt; and then press &lt;code&gt;Add&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;blockquote&gt;
&lt;p&gt;This step can take a moment because a few Nuget packages need to be installed in order for the ASP.NET Core application, the routing and the Razor pages to work.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Testing the GET method
&lt;/h2&gt;

&lt;p&gt;By default, the page is configured to receive GET requests. We will test this now.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the Index.cshtml page (in the Pages folder).&lt;/li&gt;
&lt;li&gt;Note the presence of the &lt;code&gt;@model&lt;/code&gt; directive. This is instructing ASP.NET to use the &lt;code&gt;IndexModel&lt;/code&gt; class (in &lt;a href="https://github.com/lbugnion/sample-dotnetcore-simplepostwithrazor/blob/master/src/TestPostWithRazor/Pages/Index.cshtml.cs" rel="noopener noreferrer"&gt;Index.cshtml.cs&lt;/a&gt;) to handle the calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;You can also add code directly inside the Index.cshtml page, inline with the HTML markup. This is super convenient but it can also lead to some "spaghetti" code which is very hard to test. It is not recommended to do so, except for layout code (for example &lt;code&gt;for&lt;/code&gt; loops to create lists, etc...).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Open the &lt;a href="https://github.com/lbugnion/sample-dotnetcore-simplepostwithrazor/blob/master/src/TestPostWithRazor/Pages/Index.cshtml.cs" rel="noopener noreferrer"&gt;Index.cshtml.cs&lt;/a&gt; file. This file is nested within the Index.cshtml page in the Solution explorer.&lt;/li&gt;
&lt;li&gt;Place a breakpoint within the OnGet method.&lt;/li&gt;
&lt;li&gt;Run the application in debug mode. This will start IIS Express and open a &lt;code&gt;localhost&lt;/code&gt; URL in your favorite web browser, for example &lt;code&gt;https://localhost:44367/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Notice that the breakpoint is hit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Within the method, you have access to all the usual ASP.NET objects, such as the &lt;a href="http://gslb.ch/d287b" rel="noopener noreferrer"&gt;HttpRequest&lt;/a&gt; instance (in the &lt;code&gt;Request&lt;/code&gt; property), etc.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up the POST feature
&lt;/h2&gt;

&lt;p&gt;Just like we can handle &lt;code&gt;GET&lt;/code&gt; calls in the &lt;code&gt;OnGet&lt;/code&gt; method, we will handle &lt;code&gt;POST&lt;/code&gt; calls in the &lt;code&gt;OnPost&lt;/code&gt; method. However this needs a little addition configuration as we will see. First let's prepare an HTML Form which will post a single text field to the IndexModel class.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In &lt;a href="https://github.com/lbugnion/sample-dotnetcore-simplepostwithrazor/blob/master/src/TestPostWithRazor/Pages/Index.cshtml.cs" rel="noopener noreferrer"&gt;the &lt;code&gt;IndexModel&lt;/code&gt; class&lt;/a&gt;, add a property of type &lt;code&gt;string&lt;/code&gt; named &lt;code&gt;Message&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Modify the &lt;code&gt;OnGet&lt;/code&gt; method as follows:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnGet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Enter your message here"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Still in the IndexModel class, add a method named &lt;code&gt;OnPost&lt;/code&gt;:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;OnPost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Place a breakpoint inside the &lt;code&gt;OnPost&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;Open &lt;a href="https://github.com/lbugnion/sample-dotnetcore-simplepostwithrazor/blob/master/src/TestPostWithRazor/Pages/Index.cshtml" rel="noopener noreferrer"&gt;Index.cshtml&lt;/a&gt; in the editor.&lt;/li&gt;
&lt;li&gt;Edit the &lt;code&gt;body&lt;/code&gt; as follows:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;asp-for=&lt;/span&gt;&lt;span class="s"&gt;"Message"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Run the application again in Debug mode. The &lt;code&gt;OnGet&lt;/code&gt; method will get called like before, and you should see the HTML Form with an empty input field.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;At this point, you might be surprised if like me you had expected the input field to be initialized with the content of the &lt;code&gt;Message&lt;/code&gt; property (because of &lt;a href="http://gslb.ch/d284b" rel="noopener noreferrer"&gt;the &lt;code&gt;asp-for&lt;/code&gt; attribute&lt;/a&gt;). But let's test further to see another issue.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enter any text in the field and press the Submit button.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At this point, you will get an HTTP error 400 in the browser (Bad request). &lt;/p&gt;

&lt;h2&gt;
  
  
  Fixing the Bad request error 400
&lt;/h2&gt;

&lt;p&gt;A quick online search reveals that the issue has to do with missing &lt;a href="http://gslb.ch/d285b" rel="noopener noreferrer"&gt;antiforgery tokens&lt;/a&gt;, which are a security measure put in place by ASP.NET to avoid cross-site request forgery (CSRF) attacks. In essence, what the token does is prove that the request comes from the site which the form originated from.&lt;/p&gt;

&lt;p&gt;So how do we get the token? This is where a useful namespace &lt;a href="http://gslb.ch/d283b" rel="noopener noreferrer"&gt;called &lt;code&gt;Microsoft.AspNetCore.Mvc.TagHelpers&lt;/code&gt; comes to play&lt;/a&gt;. Adding this to the CSHTML page will automatically generate the antiforgery token in the HTML form, and will also create the HTML attributes corresponding to &lt;a href="http://gslb.ch/d284b" rel="noopener noreferrer"&gt;the &lt;code&gt;asp-for&lt;/code&gt; attribute&lt;/a&gt; that we added into the form.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open Index.cshtml.&lt;/li&gt;
&lt;li&gt;On top of the file, but &lt;em&gt;below&lt;/em&gt; &lt;a href="http://gslb.ch/d286b" rel="noopener noreferrer"&gt;the &lt;code&gt;@page&lt;/code&gt; attribute&lt;/a&gt;, add &lt;a href="http://gslb.ch/d283b" rel="noopener noreferrer"&gt;the &lt;code&gt;@addTagHelper&lt;/code&gt; attribute&lt;/a&gt; so that your file looks like the following code:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;

&lt;span class="n"&gt;@page&lt;/span&gt;
&lt;span class="n"&gt;@addTagHelper&lt;/span&gt; &lt;span class="p"&gt;*,&lt;/span&gt; &lt;span class="n"&gt;Microsoft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AspNetCore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Mvc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TagHelpers&lt;/span&gt;
&lt;span class="n"&gt;@model&lt;/span&gt; &lt;span class="n"&gt;TestPostWithRazor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IndexModel&lt;/span&gt;
&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Layout&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Run the application again in Debug mode.&lt;/li&gt;
&lt;li&gt;In your web browser, once the page is loaded, you should now see the form initialized as expected:&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;Right click anywhere on the page and select &lt;code&gt;View page source&lt;/code&gt;. You should see the following HTML code that was generated by the ASP.NET application:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"Message"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"Message"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Enter your message here"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"__RequestVerificationToken"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"hidden"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"[Some token]"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Modify the content of the text field and click on the Submit button. At this point, the breakpoint in the &lt;code&gt;OnPost&lt;/code&gt; method should get hit, and the content of the field will be assigned to the &lt;code&gt;Message&lt;/code&gt; property.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;a href="https://github.com/lbugnion/sample-dotnetcore-simplepostwithrazor/tree/master/src" rel="noopener noreferrer"&gt;source code for this example is here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sometimes, simple is better. In this example, we saw how to create an empty ASP.NET Core application with a Razor page (and the corresponding &lt;code&gt;PageModel&lt;/code&gt;), and how to configure this application to handle simple &lt;code&gt;GET&lt;/code&gt; and &lt;code&gt;POST&lt;/code&gt; methods. This is an alternative to other mechanisms such as a pure client-side JavaScript powered page talking to a serverless Azure function. While the solution presented here is not serverless, you can take advantage of it if you already have an App Service plan in Azure, with Windows or Linux thanks to the cross-platform abilities of ASP.NET Core.&lt;/p&gt;

&lt;p&gt;Hopefully this code will be useful to some.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;Laurent&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>webdev</category>
      <category>aspnet</category>
      <category>razor</category>
    </item>
  </channel>
</rss>
