<?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>DEV Community: catrina</title>
    <description>The latest articles on DEV Community by catrina (@catriname).</description>
    <link>https://dev.to/catriname</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%2F21945%2F9e6953a7-caf4-4e95-9a37-5736841f2c20.JPG</url>
      <title>DEV Community: catrina</title>
      <link>https://dev.to/catriname</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/catriname"/>
    <language>en</language>
    <item>
      <title>Your Own MySQLServer (From Linux VPS to Azure Deploy)</title>
      <dc:creator>catrina</dc:creator>
      <pubDate>Wed, 23 Nov 2022 04:39:41 +0000</pubDate>
      <link>https://dev.to/catriname/your-own-mysqlserver-from-linux-vps-to-azure-deploy-396k</link>
      <guid>https://dev.to/catriname/your-own-mysqlserver-from-linux-vps-to-azure-deploy-396k</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;From VPS to Deployment on Azure&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Last year, I posted &lt;a href="https://dev.to/catriname/net-api-into-wordpress-front-end-3inh-temp-slug-5370494"&gt;&lt;strong&gt;how to include a .NET API into WordPress using a custom PHP plugin&lt;/strong&gt;&lt;/a&gt; using a free MySqlServer database as a backend.  It worked and works great – but admittedly, I slack on renewing my “free” credentials and the demo kept going down.  This week, I finally had the time to &lt;strong&gt;set up my own MySql database server for roughly $15 a year&lt;/strong&gt;.  Yep, a year.&lt;/p&gt;

&lt;p&gt;I’ve gathered the resources, from getting your own cheap Virtual Private Server and where, to the tutorials I used and the notes I took during setup, to deployment on Azure.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Getting a Cheap VPS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The holiday season is one of my favorite times to shop online for random hosting deals!! The past couple years, my fave to hunt for are “low-end vps” deals. Why? Well, it’s your own server to put any Linux distro you want on it, control and learn from, destroy, rebuild, and use it however you want. Whats not to love? Oh – right it’s cheap, and therefore a bit unstable. Some companies appear and disappear overnight, I wouldn’t consider your data absolutely not guaranteed to disappear overnight, etc. For side projects and learning purposes, though, it’s great!&lt;/p&gt;

&lt;p&gt;I have used two now that have stayed very reliable the past couple of years:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://racknerd.com"&gt;RackNerd&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;RackNerd is already live with their Black Friday sales:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.racknerd.com/BlackFriday/"&gt;https://www.racknerd.com/BlackFriday/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A peek at the VPS control panel:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.catrina.codes/wp-content/uploads/2022/11/racknerd1.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QwQDmfsu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.catrina.codes/wp-content/uploads/2022/11/racknerd1-196x300.png" alt="" width="196" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://cloudcone.com"&gt;CloudCone&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CloudCone has some competitions going on now, but also some great deals.  The best so far I got with them is 2vCPU, 2GB RAM for 19.84 per year.&lt;/p&gt;

&lt;p&gt;A peek at the VPS control panel:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.catrina.codes/wp-content/uploads/2022/11/cloudvps.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--b7vdEH1w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.catrina.codes/wp-content/uploads/2022/11/cloudvps-196x300.png" alt="" width="196" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you purchase one of their plans, the process is automated.  Your account is created, server assigned and all the admin info emailed to you.&lt;/p&gt;

&lt;p&gt;I chose the 1vCPU, 1GB RAM on RackNerd as &lt;a href="https://dev.mysql.com/doc/refman/8.0/en/memory-use.html"&gt;“the default configuration is designed to permit a MySQL server to start on a virtual machine that has approximately 512MB of RAM”&lt;/a&gt;, but also my machine is built for side projects and fun.  Nothing serious.&lt;/p&gt;

&lt;p&gt;All setup?  Choose your OS!  For this, &lt;strong&gt;I chose Ubuntu 20.04.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Access Your New VPS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You access the console using SSH:&lt;/p&gt;

&lt;p&gt;Open your choice of terminal/console and SSH:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ssh root@x.x.x.x -p 22&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The IP will be included in the email you receive after purchase.  Once you enter the SSH command up above, you’ll be asked for password (also in email).&lt;/p&gt;

&lt;p&gt;The VPS should all be setup!&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Sidenote:  DNS&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;I got my very own domain for this (more like I have a lot that I bought and are unused…) and needed to configure how to use it.&lt;/p&gt;

&lt;p&gt;I use Namecheap, and &lt;a href="https://www.namecheap.com/support/knowledgebase/article.aspx/768/10/how-do-i-register-personal-nameservers-for-my-domain/"&gt;so I created my own custom nameservers.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.catrina.codes/wp-content/uploads/2022/11/Screenshot-2022-11-22-203316.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k-7e7PPt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.catrina.codes/wp-content/uploads/2022/11/Screenshot-2022-11-22-203316-300x65.png" alt="" width="300" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pay special attention to STEP 7&lt;/em&gt;.  You must create your own A records after you create your own name servers. (IP of new VPS in the black out VPS area)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.catrina.codes/wp-content/uploads/2022/11/Screenshot-2022-11-22-203335.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bmAk4UgB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.catrina.codes/wp-content/uploads/2022/11/Screenshot-2022-11-22-203335-300x55.png" alt="" width="300" height="55"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;LAMP Stack&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;My very first websites used to be on a LAMP stack and the reason was easy:  cheap.  What is a lamp stack?  Linux (OS), Apache (WebServer), MySql (Database), PhpMyAdmin (Database Management UI).  If you didn’t know before, it all makes sense now, right?  All the components you need for web dev!&lt;/p&gt;

&lt;p&gt;These days, I prefer .NET but with it now being cross platform, it’s time to explore that stack again (yes, you still need to install php as it runs phpMyAdmin on this server).&lt;/p&gt;

&lt;p&gt;I won’t create my own tutorial, there’s PLENTY of how to install a LAMP stack on your new VPS server, but here’s the one I used and my notes after I did the basic install on VPS:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-20-04"&gt;https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-20-04&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
After my basic install of Ubuntu from VPS control panel, I did have to install ufw:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install ufw
sudo ufw enable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and add don’t forget to allow SSH (you know, so you can get back in…so i heard…) :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ufw allow ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then continue to allow “apache full” (from tutorial)&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Let’s Encrypt SSL&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After full install, I added SSL:&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-20-04"&gt;https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-20-04&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pretty straight forward install and if you were able to view your Apache site in tutorial, it should all go well.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Notes: *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Remember by default, Let’s Encrypt expires every 90 days, so pay special attention to email reminders and the commands in tutorial on how to renew.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;phpMyAdmin&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Coming to the end, oh, I have a special place in my heart for phpMyAdmin.  You import/export sql files. You can run all the commands to your little hearts desire and test and try all you want – in your very own playground!  This particular UI was very easy for me to get hands on with a database.  If you’ve been afraid to mess with a database NOW is that time.  It’s your server, your playground.&lt;/p&gt;

&lt;p&gt;Let’s set it up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-phpmyadmin-on-ubuntu-20-04"&gt;https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-phpmyadmin-on-ubuntu-20-04&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Notes:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
With default install (Ubuntu 20.04), I could not find: /etc/apache2/conf-available/phpmyadmin.conf in Step 3.&lt;/p&gt;

&lt;p&gt;Fix:&lt;br&gt;&lt;br&gt;
&lt;a href="https://askubuntu.com/questions/387062/how-to-solve-the-phpmyadmin-not-found-issue-after-upgrading-php-and-apache"&gt;https://askubuntu.com/questions/387062/how-to-solve-the-phpmyadmin-not-found-issue-after-upgrading-php-and-apache&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf-available/phpmyadmin.conf
sudo a2enconf phpmyadmin.conf
sudo systemctl restart apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From comments, I also did the following change in same file above:&lt;br&gt;&lt;br&gt;
soleraeus&lt;br&gt;&lt;br&gt;
…&lt;br&gt;&lt;br&gt;
You can go a step further to avoid script attacks by changing the route to phpmyadmin in /etc/apache2/conf-available/phpmyadmin.conf Just change at the beginning of the file “Alias /phpmyadmin /usr/share/phpmyadmin” by “Alias /yourcustomroute /usr/share/phpmyadmin” Makes it even harder to find and really does not tell attackers what is behind the access point if you use a good name.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;.NET&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You CAN use Entity Framework and you can continue on with all the tutorials and help.  But some modifications I made:&lt;/p&gt;

&lt;p&gt;Add the following package:  MySql.EntityFrameworkCore&lt;/p&gt;

&lt;p&gt;If you are deploying into Azure Portal, your connection string should look something like this:&lt;br&gt;&lt;br&gt;
string connString = System.Environment.GetEnvironmentVariable(“MYSQLCONNSTR_CustomName”);&lt;/p&gt;

&lt;p&gt;An example of it used in DbContext:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MyAppContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(System.Environment.GetEnvironmentVariable("MYSQLCONNSTR_CustomName"));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Azure Portal&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Ok, coming to end.  When I first saw Azure Portal I was like this is like WHM on Boss Level?  a CPanel Plus?  If you’ve ever dealt with a LAMP stack and control panels, this .NET control.. “central?”.  Larger than WHM as it holds much more than just web services.  But that is not our concern right now.  For resources,&lt;/p&gt;

&lt;p&gt;Create Web App Service and every “service” requires a plan, so:&lt;/p&gt;

&lt;p&gt;Pricing Plan:&lt;br&gt;&lt;br&gt;
Free F1&lt;br&gt;&lt;br&gt;
Shared infrastructure, 1 GB memory&lt;/p&gt;

&lt;p&gt;Within Web AppService go to:&lt;br&gt;&lt;br&gt;
Configuration &amp;gt; Connection Strings&lt;/p&gt;

&lt;p&gt;Specify name after _ (dash) and select MySQL from drop down, entering your connection string as value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.catrina.codes/wp-content/uploads/2022/11/Screenshot-2022-11-22-182354.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yR9doVyQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.catrina.codes/wp-content/uploads/2022/11/Screenshot-2022-11-22-182354-300x80.png" alt="" width="300" height="80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Final result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.catrina.codes/wp-content/uploads/2022/11/Screenshot-2022-11-22-182333.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kin2_1t8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.catrina.codes/wp-content/uploads/2022/11/Screenshot-2022-11-22-182333-300x50.png" alt="" width="300" height="50"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hit the Save button up top and done.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Still no MySql Access:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Edit mySql config:&lt;br&gt;&lt;br&gt;
Default configuration in MySQL only allows it to listen to localhost.  To edit that config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;comment out:  &lt;/p&gt;

&lt;h1&gt;
  
  
  bind-address = 127.0.0.1
&lt;/h1&gt;

&lt;p&gt;save, restart mysql:&lt;br&gt;&lt;br&gt;
sudo service mysql restart&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Your Own MySQLServer&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;It should all be set up and ready to go!&lt;/p&gt;

&lt;p&gt;The current demo here: &lt;a href="https://dev.to/catriname/net-api-into-wordpress-front-end-3inh-temp-slug-5370494"&gt;https://www.catrina.codes/net-api-into-wordpress-front-end/  is running on it.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let me know if your own MySqlServer on a LowEnd VPS Running!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>mysql</category>
      <category>linux</category>
      <category>vps</category>
    </item>
    <item>
      <title>Making Session Variables Work in .NET Core</title>
      <dc:creator>catrina</dc:creator>
      <pubDate>Tue, 09 Apr 2019 01:51:55 +0000</pubDate>
      <link>https://dev.to/catriname/making-session-variables-work-in-net-core-3599</link>
      <guid>https://dev.to/catriname/making-session-variables-work-in-net-core-3599</guid>
      <description>

&lt;p&gt;As noted, I work with Legacy and often have to bring in variables from the API that must be sustained across session.. (and I’m sure there might be a better way, comment and advise!).  Where I am at now, is I query the API, bring in the variables but how do I keep from calling these over and over: old solution was session variables so, that’s where I am at.&lt;/p&gt;

&lt;p&gt;When I started to do this on Core, the most helpful article was this (and it’s in my comments):  &lt;a href="https://adamstorr.azurewebsites.net/blog/are-you-registering-ihttpcontextaccessor-correctly"&gt;https://adamstorr.azurewebsites.net/blog/are-you-registering-ihttpcontextaccessor-correctly&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;He leads you through the basic setup of a HttpContext helper class (that I still use today) and how to configure the startup..  and maybe I strayed, but today I came across a problem: I was able to Set session variables, but the Get was pulling null.&lt;/p&gt;

&lt;p&gt;Why!!??&lt;/p&gt;

&lt;p&gt;Order.  Yes, you’ll see 1000 stackflow responses about order in Configure, but now in &lt;strong&gt;ConfigureServices&lt;/strong&gt; (contrary to example as I am now using Core 2.2?), order again comes into play:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void ConfigureServices(IServiceCollection services){ //this MUST be before add mvc or session returns null services.AddSingleton&amp;lt;IHttpContextAccessor, HttpContextAccessor&amp;gt;(); services.AddMvc();
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;How does the error present itself?  Full Post: &lt;a href="https://www.catrina.me/making-session-variables-work-in-net-core/"&gt;https://www.catrina.me/making-session-variables-work-in-net-core/&lt;/a&gt;&lt;/p&gt;


</description>
      <category>dailydevelopment</category>
      <category>core</category>
      <category>dotnet</category>
      <category>errors</category>
    </item>
    <item>
      <title>First Heroku App: Small API in PHP to Talk to .Net Core</title>
      <dc:creator>catrina</dc:creator>
      <pubDate>Fri, 22 Feb 2019 00:59:51 +0000</pubDate>
      <link>https://dev.to/catriname/first-heroku-app-small-api-in-php-to-talk-to-net-core-4783</link>
      <guid>https://dev.to/catriname/first-heroku-app-small-api-in-php-to-talk-to-net-core-4783</guid>
      <description>&lt;p&gt;I've recently been curious about switching to a time API for my time stamps and removing any dependency the app might have on the server for a timestamp.  Upon Googling I found some paid services, some free and of the free ones, I noticed one was hosted on Heroku.  I've heard of Heroku, but never had a reason to attempt to use it.  This was the perfect chance.&lt;/p&gt;

&lt;h2&gt;How I Created a Small "GetTime" API&lt;/h2&gt;

&lt;p&gt;First, I created a free account on Heroku, nothing special.  After verifying my email, I logged in to my Heroku Dashboard and up on the right hand corner, selected Create New App.  I named it my company-api and out popped an app.&lt;/p&gt;

&lt;p&gt;I decided on just plain, legacy PHP and a simple DateTime string passed thru JSON encode, just to get started.  No authentication, no timezone,  just a simple spit out if a request to the site came, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;    &lt;span class="nb"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Content-type:application/json;charset=utf-8'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$DateTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nv"&gt;$currentTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$DateTime&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Y-m-d H:i:s"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nb"&gt;json_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$currentTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I created a Git repo for this brand new file and pushed it out.  Then, I went back to Heroku, Dashboard, My App and Deploy.  I selected Github as my deploy "resource" and selected the new repo I just made along with correpsonding branch.&lt;/p&gt;

&lt;p&gt;I hit manual deploy and Heroku runs off to my GitHub repo, grabs the code, compiles and publishes.&lt;/p&gt;

&lt;p&gt;It failed.&lt;/p&gt;

&lt;h2&gt;Beginner Troubles&lt;/h2&gt;

&lt;p&gt;My first problem was that Heroku could not determine what language I had chosen for my app (you'd think the &amp;lt;?php would give it away ...).  You need either one of two things:  a composer.json file or an index.php file (for legacy, like mine).  I renamed my file to index.php and all I needed now was a "builder pack".&lt;/p&gt;

&lt;p&gt;To add a builder pack, I went back to Heroku, Dashboard, My App and Settings.  Under builder pack, I added one for: "php".  Save settings and done.&lt;/p&gt;

&lt;p&gt;I went back to Deploy, Manual Deploy and had a successful output.  Yay!  First Heroku app!&lt;/p&gt;

&lt;h2&gt;Adding Some Security&lt;/h2&gt;

&lt;p&gt;I want to make sure this API is receiving and sending JSON, so there's a few IF's I make the request go through before I hit logic on my PHP page.  I also want to (lightly) secure the requests made to this API and monitor our usage of it for metrics information (and future investment).  Since this itty bitty API is just relying on 1 index.php file, I figure this can be a sort of "router" for future API's.  So, this is what I added to the final PHP file:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;Verify the request is in JSON&lt;/li&gt;
    &lt;li&gt;Require two variables passed:
&lt;ul&gt;
    &lt;li&gt;a secret api "key"&lt;/li&gt;
    &lt;li&gt;an api "request"&lt;/li&gt;
&lt;/ul&gt;




&lt;/li&gt;


    &lt;li&gt;Use a switch statement to forward to needed method&lt;/li&gt;


&lt;/ul&gt;
&lt;br&gt;&lt;br&gt;
The final, simple 1 page PHP Heroku API:&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="nb"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Content-type:application/json;charset=utf-8'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//Make sure that it is a POST request.&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;strcasecmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_SERVER&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'REQUEST_METHOD'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s1"&gt;'POST'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Request method must be POST!'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//Make sure that the content type of the POST request has been set to application/json&lt;/span&gt;
&lt;span class="nv"&gt;$contentType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_SERVER&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CONTENT_TYPE"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$_SERVER&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"CONTENT_TYPE"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$contentIsJson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;strpos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$contentType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"application/json"&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="nv"&gt;$contentIsJson&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Content type must be: application/json'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//Receive the RAW post data.&lt;/span&gt;
&lt;span class="nv"&gt;$content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;file_get_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"php://input"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;//Attempt to decode the incoming RAW post data from JSON.&lt;/span&gt;
&lt;span class="nv"&gt;$decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;json_decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;strtoupper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$decoded&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'API'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$decoded&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'APIKEY'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;//verify user key - simple MD5 generator: http://onlinemd5.com/.  will build user management for keys if ever needed&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"BEAF1CB722A3F7758C7A7FA43F6BF2D1"&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;   

    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"TIME"&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="nv"&gt;$jsonString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="nv"&gt;$arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'datetime'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$jsonString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
            &lt;span class="nv"&gt;$arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'error'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Unknown Request On API"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;  

    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nb"&gt;json_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$arr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;//return the current time&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getTime&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$DateTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;//by default heroku returns time in UTC - can change in dashboard, config vars, only use as needed below&lt;/span&gt;
    &lt;span class="c1"&gt;//$DateTime-&amp;gt;modify('-6 hours');&lt;/span&gt;
    &lt;span class="nv"&gt;$currentTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$DateTime&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Y-m-d H:i:s"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nv"&gt;$jsonString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$currentTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$jsonString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



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

&lt;h2&gt;Verifying the Response&lt;/h2&gt;

&lt;p&gt;I used Postman to send a raw JSON request to my Heroku app (used their default/free url).  I wanted to make sure all my problems were resolved with this new toy, first, and then move on.  Here's what the raw request and response look like on Postman:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.catrina.me/wp-content/uploads/2019/02/rawRequest.jpg" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.catrina.me%2Fwp-content%2Fuploads%2F2019%2F02%2FrawRequest-1024x488.jpg" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Heroku + my PHP are responding nicely!&lt;/p&gt;

&lt;h2&gt;Handling the Request and Response in C#&lt;/h2&gt;

&lt;p&gt;So here's how I did the same request and received the response in C# (I use dotnet Core):&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;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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;OurHerokuAPI&lt;/span&gt;&lt;span class="p"&gt;()&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;reqUrl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://mycompany-api.herokuapp.com"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;using&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;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultRequestHeaders&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Accept&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;new&lt;/span&gt; &lt;span class="nf"&gt;MediaTypeWithQualityHeaderValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="k"&gt;try&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;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;APIKEY&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"BEAF1CB722A3F7758C7A7FA43F6BF2D1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"time"&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;asJson&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JsonConvert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SerializeObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;HttpResponseMessage&lt;/span&gt; &lt;span class="n"&gt;response&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;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PostAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reqUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StringContent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asJson&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTF8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/json"&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSuccessStatusCode&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;definition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&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;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JsonConvert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DeserializeAnonymousType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAsStringAsync&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="c1"&gt;//monitors success across various "time" api's. in case this particular one fails, there can be various backups until success flag returns true.&lt;/span&gt;
                &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&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;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OperationCanceledException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//TODO: CREATE ERROR MESSAGE SEND BACK TO EMAIL/ERROR &lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;time&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; &lt;/p&gt;

&lt;p&gt;If you see notes, yes, I decided to have some fun and create maybe two other functions, just like the one above, where I query some "free" time api's until that "success" flag turns true (of course, times are controlled to same format).  After x tries, I reluctantly call my last function, that gets the server timestamp.  As said, I wanted my timestamp to be independent of server.  So, if it hits this last method, I also send myself an error email that the time API is failing.&lt;/p&gt;

&lt;p&gt;In the future, I could  use environment variables (&lt;a href="https://devcenter.heroku.com/articles/config-vars" rel="noopener noreferrer"&gt;config vars&lt;/a&gt;) more wisely, instead of hardcoding.  There's also so much clean up to do, but this was a very fun intro into Heroku!&lt;/p&gt;

</description>
      <category>heroku</category>
      <category>php</category>
      <category>dotnet</category>
      <category>core</category>
    </item>
    <item>
      <title>Why Watch Coders Stream Live</title>
      <dc:creator>catrina</dc:creator>
      <pubDate>Sun, 21 Oct 2018 12:44:44 +0000</pubDate>
      <link>https://dev.to/catriname/why-watch-coders-stream-live-ned</link>
      <guid>https://dev.to/catriname/why-watch-coders-stream-live-ned</guid>
      <description>&lt;p&gt;I began hearing about live code streams a year or so ago on &lt;a href="http://www.liveedu.tv"&gt;LiveEdu.TV&lt;/a&gt; and saw a livestream with &lt;a href="https://www.twitch.tv/csharpfritz"&gt;Jeff Fritz&lt;/a&gt; at DevIntersection, but I decided to become a regular on a stream called &lt;a href="https://www.twitch.tv/devchatter"&gt;DevChatter&lt;/a&gt; a few months ago to really see how it could improve my own code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a Community
&lt;/h2&gt;

&lt;p&gt;I specifically joined the &lt;a href="https://www.twitch.tv/devchatter"&gt;DevChatter&lt;/a&gt; stream because they had a &lt;a href="https://discord.gg/aQry9jG"&gt;Discord chat&lt;/a&gt;. I wasn't familiar with Discord, but I've spent time on IRC. I was expecting 3 months of ignoring, bad advice, trolling to make me go away, you know - the standard IRC vetting experience. &lt;a href="https://discord.gg/aQry9jG"&gt;DevChatter's Discord&lt;/a&gt; was actually VERY welcoming!&lt;/p&gt;

&lt;p&gt;I like that they have a General chat but also VERY specific chats, like #azure, #dotnet, #php and.. #rants. &lt;/p&gt;

&lt;p&gt;Regular dev's go onto that Discord chat asking for random code help, spitting ideas off each other or just ranting about the problem of the day: the bug that wouldn't go away, the pains of working with legacy, the random programming problem that won't leave your mind... &lt;/p&gt;

&lt;p&gt;Every portion of that Discord chat lends you a bit of insight into this person. You figure out what timezone they are in, what languages and systems they work with. You start to know these users not just as chatters, but as developers, as everyday people, working and programming just like you. &lt;/p&gt;

&lt;p&gt;It is a community working together to improve their code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn Your Environment
&lt;/h2&gt;

&lt;p&gt;I work in Visual Studio all day. I code in Visual Studio, research on Firefox, debug on Firefox and back to Visual Studio. On my most focused days, nothing else exists. &lt;/p&gt;

&lt;p&gt;But, I'm still quite new to VS. I'm not completely sure what CodeRush or Resharper might offer me and I'm not even sure what I WANT in an environment. That is, until I saw someone else work in it. &lt;/p&gt;

&lt;p&gt;If I pick up nothing else, watching a live code stream gives me the experience of seeing how quickly and efficiently a seasoned programmer works. &lt;/p&gt;

&lt;p&gt;A live coding stream puts you face to face with an environment in real-time and makes you rethink your choice of IDE, extensions, plugins, etc. It makes you want to make your own experience as efficient as possible. &lt;/p&gt;

&lt;p&gt;One stream, I got completely obsessed with the comment code and how a TODO comment stood out differently from a regular comment. I commented on this on livestream and I got various suggestions on how to make it happen. &lt;/p&gt;

&lt;p&gt;There are constant comments every stream about what extensions to use, Visual Studio vs Visual Code, etc and each time, it is someone is discovering a way to improve their environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conquer Your Imposter Syndrome
&lt;/h2&gt;

&lt;p&gt;Some of the best streams I've attended were a struggle to just get going.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Imported library wouldn't work.&lt;/li&gt;
&lt;li&gt;  Firefox error message is vague.&lt;/li&gt;
&lt;li&gt;  Project is getting too big for the logic behind it...&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Speak Up
&lt;/h3&gt;

&lt;p&gt;When live coding, the community takes every chance to offer their own experience to help. It can be a simple.."err, I got that error message before.. I was missing a JS file.." or it can be a more complicated logic refactor suggestion. &lt;/p&gt;

&lt;p&gt;When errors happen on live stream, you have this urge to just spout ideas. Your doubts about your expertise are less important - you're just trying to help solve this! Everyone understands.&lt;/p&gt;

&lt;h3&gt;
  
  
  Act
&lt;/h3&gt;

&lt;p&gt;I saw a DevChatter stream fail with a 3rd party library, they fixed it and filed a GitHub issue. Though version control and GitHub have long been in my work process, I never got comfortable filing issues. As a sole full stack developer, seeing him do this live made me just a bit more confident to speak up. &lt;/p&gt;

&lt;p&gt;I finally filed my own first issue on a library I work with last week: &lt;a href="https://github.com/aspnet/LibraryManager/issues/383"&gt;Libman&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Be Confident
&lt;/h3&gt;

&lt;p&gt;Everyone gets stuck and Googles, StackOverflows and sometimes narrow it down on a CodePen route. You learn you're not alone. &lt;/p&gt;

&lt;p&gt;Live coding is a great environment to simulate the pressure of creating an app and fixing a bug live. The only difference is that the satisfaction is shared by everyone on the livestream, too!&lt;/p&gt;

&lt;h2&gt;
  
  
  No Pressure
&lt;/h2&gt;

&lt;p&gt;What I also like about live code streaming is access to this level of a professional coding community without the pressure of always participating. &lt;/p&gt;

&lt;p&gt;If you've attended conferences, names you know, like: &lt;a href="https://www.twitch.tv/csharpfritz"&gt;JeffFritz&lt;/a&gt; - runs a great streaming channel. &lt;a href="https://www.twitch.tv/visualstudio"&gt;VisualStudio&lt;/a&gt; started their own Twitch channel not to long ago and I've also seen &lt;a href="https://www.twitch.tv/jamesmontemagno"&gt;JamesMontemagno&lt;/a&gt; stream recently. I latched onto the &lt;a href="https://www.twitch.tv/devchatter"&gt;DevChatter&lt;/a&gt; community. &lt;/p&gt;

&lt;p&gt;But, I'm mostly a lurker. &lt;/p&gt;

&lt;p&gt;I'm usually coding during the day for work and put a stream off to the 2nd or maybe half screen. I'm often not even sure how long I can stay. This doesn't mean I can't learn anything off that stream!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Maybe a couple of devs had a random fight of F# vs C# and I get some new tips on F#!&lt;/li&gt;
&lt;li&gt;  Maybe the 30 minutes I &lt;em&gt;do&lt;/em&gt; see teaches me a new way to debug JavaScript.&lt;/li&gt;
&lt;li&gt;  Maybe we all just bag on the &lt;em&gt;obscene use of var&lt;/em&gt; and we all get a little more strict on our typing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are the reasons I keep it on and will continue to participate in live code streams.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>codelive</category>
      <category>stream</category>
    </item>
    <item>
      <title>Print PDF’s on Azure Using an API and RazorLight (Update 1)</title>
      <dc:creator>catrina</dc:creator>
      <pubDate>Tue, 16 Oct 2018 14:53:57 +0000</pubDate>
      <link>https://dev.to/catriname/print-pdfs-on-azure-using-an-api-and-razorlight-update-1-20kb</link>
      <guid>https://dev.to/catriname/print-pdfs-on-azure-using-an-api-and-razorlight-update-1-20kb</guid>
      <description>&lt;p&gt;The API mentioned &lt;a href="https://dev.to/catriname/print-pdf-using-a-3rd-party-app-and-razorlight-deploy-to-azure-1453"&gt;in my first tutorial&lt;/a&gt; got taken down and so I had to do some updates.  First, choose another 3rd party API.  I currently am trying out  &lt;a href="https://www.html2pdfrocket.com/"&gt;HTML 2 PDF Rocket&lt;/a&gt; and modified my code a bit:&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="n"&gt;HttpGet&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;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;FileStreamResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;PrintAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;InvoiceVM&lt;/span&gt; &lt;span class="n"&gt;invoiceVM&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;InvoiceVM&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;invoiceVM&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;invoiceRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&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;engine&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RazorLightEngineBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseFilesystemProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_hostingEnvironment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebRootPath&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"\\pdf\\"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseMemoryCachingProvider&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&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;view&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;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CompileRenderAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PDF.cshtml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;invoiceVM&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;apiKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"xxxxxxxxxxxxxxxxxxxx"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;using&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;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebClient&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Build the conversion options&lt;/span&gt;
            &lt;span class="n"&gt;NameValueCollection&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NameValueCollection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;options&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="s"&gt;"apikey"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;options&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="s"&gt;"value"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;options&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="s"&gt;"MarginLeft"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"10"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;options&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="s"&gt;"MarginRight"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"10"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;options&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="s"&gt;"MarginTop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"10"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;options&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="s"&gt;"MarginBottom"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"10"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;options&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="s"&gt;"PageSize"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Letter"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;MemoryStream&lt;/span&gt; &lt;span class="n"&gt;ms&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UploadValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://api.html2pdfrocket.com/pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStreamResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/pdf"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is based directly off the HTML 2 Rocket documentation.  For the &lt;a href="https://dev.to/catriname/print-pdf-using-a-3rd-party-app-and-razorlight-deploy-to-azure-1453"&gt;rest of the code see the first tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;…&lt;/p&gt;

</description>
      <category>core</category>
      <category>azure</category>
      <category>pdf</category>
    </item>
    <item>
      <title>Using Libman Providers to Coral Front End Libraries</title>
      <dc:creator>catrina</dc:creator>
      <pubDate>Mon, 15 Oct 2018 20:59:25 +0000</pubDate>
      <link>https://dev.to/catriname/using-libman-providers-to-coral-front-end-libraries-2cbf</link>
      <guid>https://dev.to/catriname/using-libman-providers-to-coral-front-end-libraries-2cbf</guid>
      <description>&lt;p&gt;The first package management system I learned to use was Bower.  It was great for the short love affair we had together, but it stopped being supported and I was weary of learning to use one of its replacements.  Fortunately, I haven’t had to with Libman.  &lt;/p&gt;

&lt;p&gt;Libman’s (Library Manager) simple JSON approach to bringing front end dependencies has been the easiest for me quickly implement and it has been a great addition to Visual Studio.  I implemented it possibly too quickly, however, and &lt;strong&gt;overlooked one powerful configuration setting:  provider.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Library Not On Libman!
&lt;/h2&gt;

&lt;p&gt;That was my first sign of trouble, but what actually happened:  I didn’t specify the right &lt;strong&gt;provider&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The defaultProvider I specified was cdnjs, like the many examples out there, and though it has a lot of front end libraries, &lt;em&gt;cdnjs, of course, doesn’t have all libraries.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here’s a simple example of how Libman successfully does use cdnjs to bring in jQuery:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"defaultProvider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cdnjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"libraries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"library"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jquery@3.3.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wwwroot/lib/jquery"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"jquery.min.js"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Libman Provider Options
&lt;/h2&gt;

&lt;p&gt;In addition to CDNJS, Libman supports two other providers.  Here is the complete list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cdnjs (default provider)&lt;/li&gt;
&lt;li&gt;filesystem (local files)&lt;/li&gt;
&lt;li&gt;unpkg (a CDN for everything on NPM) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This works great and&lt;strong&gt; if a dependency didn't resolve, I added a provider line, changing it's provider:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"unpkg"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"library"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bulma-checkradio"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wwwroot/lib/bulma"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  UNPKG Library Could Not Be Resolved
&lt;/h2&gt;

&lt;p&gt;When using unpkg as a provider, though, I couldn't get any files to list in Intellisense.  I simply got no results.  I also got no versions on the library.&lt;/p&gt;

&lt;p&gt;So, I did a bit of a hack and used the 3rd option for provider: filesystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Local Files
&lt;/h2&gt;

&lt;p&gt;I had 2 particular packages that would show on unpkg, but return the following errors:&lt;/p&gt;

&lt;p&gt;The "bulma-checkradio" library could not be resolved by the "unpkg" provider&lt;br&gt;
The "datatables-bulma" library could not be resolved by the "unpkg" provider&lt;br&gt;
Restore operation completed with errors&lt;/p&gt;

&lt;p&gt;So, I imported them via NPM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"myproject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"devDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"bulma-checkradio"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"datatables-bulma"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.0.1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"-vs-binding"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"BeforeBuild"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"update"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But I didn't want to add my _node_modules folder to the project, making NPM packages unable to be brought into Views.  So, I used Libman to copy the files from the _node_modules folder into my wwwroot/lib folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"filesystem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"library"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node_modules/bulma-checkradio/dist/css/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wwwroot/lib/bulma/bulma-checkradio/css"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"bulma-checkradio.min.css"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works, just wishing this was a bit smoother.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>libman</category>
      <category>core</category>
    </item>
    <item>
      <title>.Net Core – Drop Down (Select) Won’t Populate</title>
      <dc:creator>catrina</dc:creator>
      <pubDate>Wed, 10 Oct 2018 16:06:27 +0000</pubDate>
      <link>https://dev.to/catriname/net-core--drop-down-select-wont-populate-2d07</link>
      <guid>https://dev.to/catriname/net-core--drop-down-select-wont-populate-2d07</guid>
      <description>&lt;p&gt;I had a recent bug that took me much too long to solve and the root of the cause was me. I got a bit too delete happy and deleted a crucial file that allows me to use Razor Tag Helpers to bring a List into a View as a Drop Down (Select).&lt;/p&gt;

&lt;h1&gt;
  
  
  The Error
&lt;/h1&gt;

&lt;p&gt;Here’s how the error presented itself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SelectList won’t populate&lt;/li&gt;
&lt;li&gt;Select or DropDown is empty&lt;/li&gt;
&lt;li&gt;value = Microsoft.AspNetCore.Mvc.Rendering.SelectList&lt;/li&gt;
&lt;li&gt;value = System.Linq.OrderedEnumerable2 [Microsoft.AspNetCore.Mvc.Rendering.SelectListItem,System.String]&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  My Code
&lt;/h1&gt;

&lt;p&gt;This is how I usually bring a list into my view and the code does work once the solution is implemented.&lt;/p&gt;

&lt;h3&gt;
  
  
  Controller:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;    &lt;span class="n"&gt;ViewBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProductLines&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;productLineRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SelectListItem&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="n"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&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="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;OrderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  View:
&lt;/h3&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;select&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"ProductLine"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"ProductLine"&lt;/span&gt; &lt;span class="na"&gt;asp-for=&lt;/span&gt;&lt;span class="s"&gt;"ProductLine"&lt;/span&gt; &lt;span class="na"&gt;asp-items=&lt;/span&gt;&lt;span class="s"&gt;"@ViewBag.ProductLines"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Select One...&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  The Solution
&lt;/h1&gt;

&lt;p&gt;The solution is a bit embarrasing: I deleted the _ViewImports.cshtml view which included an import that enables tag helpers. The list was not rendering because tag helpers was not enabled.&lt;/p&gt;

&lt;p&gt;To solve this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create a file named “_ViewImports.cshtml” directly under your Views folder&lt;/li&gt;
&lt;li&gt;add the following into it:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@using MyNameSpace @addTagHelper \*, Microsoft.AspNetCore.Mvc.TagHelpers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;save file and refresh.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pretty simple fix!&lt;/p&gt;

</description>
      <category>core</category>
      <category>razor</category>
      <category>csharp</category>
    </item>
    <item>
      <title>I’m a Front-End Cheater</title>
      <dc:creator>catrina</dc:creator>
      <pubDate>Wed, 08 Aug 2018 02:29:43 +0000</pubDate>
      <link>https://dev.to/catriname/im-a-front-end-cheater-65k</link>
      <guid>https://dev.to/catriname/im-a-front-end-cheater-65k</guid>
      <description>&lt;p&gt;I am a full stack developer.  I develop in Visual Studio, code in C# with .NET Core, deploy to Azure and I must admit, I'm a front-end cheater.&lt;/p&gt;

&lt;p&gt;Comeon, the .NET Core Web App demo itself loads with Bootstrap and JQuery preinstalled.  We're all cheaters at some point, but I'm trying to diversify my cheating and eliminate my dependencies.&lt;/p&gt;

&lt;p&gt;Here's my latest strategy.&lt;/p&gt;

&lt;h1&gt;
  
  
  Goodbye Bootstrap, HELLO Bulma!
&lt;/h1&gt;

&lt;p&gt;Anything Bootstrap can do, Bulma can do better!&lt;/p&gt;

&lt;p&gt;Well, not exactly but let me explain why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bulma has NO JS file.
&lt;/h2&gt;

&lt;p&gt;The only time I feel a need for JS?   Maybe JQuery Datatables, but I make a specific "DataTableLayout" and only use JQuery tables if required.  This coupling of Bootstrap and JQuery is itself what I was trying to move away from.&lt;/p&gt;

&lt;p&gt;Almost everything else? Columns, tables, hero images? Bulma does it all!  &lt;/p&gt;

&lt;h2&gt;
  
  
  I want style to be style.
&lt;/h2&gt;

&lt;p&gt;I'm not a fan of my hover, form validation, etc being done by JS.  HTML5 has increased it's validation options, and CSS is rich in transformation.  Why am I forced to bring in JQuery and then various animation libraries just to get some simple text animation.&lt;/p&gt;

&lt;p&gt;It's frustrating to have so much code that I'm dependent on when I can do columns, tables, cover designs, and more with ONE SINGULAR CSS file:  Bulma.  &lt;/p&gt;

&lt;h1&gt;
  
  
  I want flair!
&lt;/h1&gt;

&lt;p&gt;So this works great, everything loads quickly but there's no "animation", no "flair". &lt;/p&gt;

&lt;p&gt;What now?  Do I succumb and just go ahead and import JQuery and WOW.js?  I mean I could...&lt;/p&gt;

&lt;p&gt;Or, I could pick and choose my animations with something like : &lt;a href="http://animista.net"&gt;Animista&lt;/a&gt;.  It has a great UI, I can pick and choose &lt;em&gt;exactly&lt;/em&gt; what I need and nothing else.  If there's ever a problem, well, I comment out that CSS and back to plan Bulma we go!&lt;/p&gt;

&lt;h1&gt;
  
  
  Example
&lt;/h1&gt;

&lt;p&gt;So, I wanted to do a simple mouse over.  User mouses-over image and words appear.  I followed the basic &lt;a href="https://www.w3schools.com/howto/howto_css_image_overlay.asp"&gt;CSS/HTML example from W3Schools&lt;/a&gt; and got that to work pretty quickly (I replaced the "container" with the "flip" class to avoid Bulma conflicts).&lt;/p&gt;

&lt;p&gt;For flair, I visited &lt;a href="http://animista.net/play/text/focus-in"&gt;Animista for an example of a slight blur-to-focus on words&lt;/a&gt; and worked to combine it's animation with my mouseover.  This is the result...&lt;/p&gt;

&lt;p&gt;Here's the HTML:&lt;br&gt;
&lt;/p&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flip"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"~/images/flip_images/branches.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Avatar"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flip-image"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"width:100%"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flip-middle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flip-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/Home/Locations"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;LOCATIONS&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"is-size-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Over 80 Years of Service&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's the CSS (a combo of the W3 + Animista):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.flip&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.3rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.flip-image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;.5s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;backface-visibility&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.flip-middle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;.5s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-50%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;-50%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;-ms-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-50%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;-50%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.flip&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="nc"&gt;.flip-image&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.flip&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="nc"&gt;.flip-middle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c"&gt;/* below credit of Animista*/&lt;/span&gt;
    &lt;span class="nl"&gt;-webkit-animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text-focus-in&lt;/span&gt; &lt;span class="m"&gt;.5s&lt;/span&gt; &lt;span class="n"&gt;cubic-bezier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.550&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.085&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.680&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.530&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;both&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;text-focus-in&lt;/span&gt; &lt;span class="m"&gt;.5s&lt;/span&gt; &lt;span class="n"&gt;cubic-bezier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.550&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.085&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.680&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.530&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;both&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.flip-text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.125&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#565656&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* ----------------------------------------------
 * Generated by Animista on 2018-8-7 13:40:21
 * w: http://animista.net, t: @cssanimista
 * ---------------------------------------------- */&lt;/span&gt;

&lt;span class="c"&gt;/**
 * ----------------------------------------
 * animation text-focus-in
 * ----------------------------------------
 */&lt;/span&gt;
&lt;span class="k"&gt;@-webkit-keyframes&lt;/span&gt; &lt;span class="n"&gt;text-focus-in&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;-webkit-filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;-webkit-filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&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;@keyframes&lt;/span&gt; &lt;span class="n"&gt;text-focus-in&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;-webkit-filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;12px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;-webkit-filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&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="c"&gt;/* ---------------------------------------------- */&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The result is a simple animation:  you mouse-over an image, it fades and a transparent, white overlay appears.  An animated word blurs into focus at dead center so that you can click to follow the link.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pure CSS! (Bulma + Animista mods)&lt;/p&gt;

&lt;h1&gt;
  
  
  So, Why So Much Trouble?
&lt;/h1&gt;

&lt;p&gt;I had a site last year that was and IS crucial.  It accepted payments.  It required a very specific version of JQuery for its own library to work, encrypt credit card numbers and send to API (thus  not storing and avoiding PCI compliance).  That's fine, but with the design I had then, I had a different version of JQuery, along with a slew of libraries.  The libraries did everything from cover background images, to animation, to form validation and whatnot.  I stripped everything down and it did work.  Somewhere in there, though, one of the libraries clashed with a new release of Edge and caused tons of complaints about invalid credit cards via API.  All errors related to form dropdowns in Edge.&lt;/p&gt;

&lt;p&gt;Chrome and Firefox handled it fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  TLDR; Summary, Lesson Learned:
&lt;/h2&gt;

&lt;p&gt;MINIMIZE YOUR DEPENDENCIES.&lt;br&gt;
and that's what I've started to do.&lt;/p&gt;

</description>
      <category>bulma</category>
      <category>dotnetcore</category>
      <category>css</category>
    </item>
    <item>
      <title>Using Microsoft Flow to Sync BaseCamp &amp; VSTS (To-Do to Tasks)</title>
      <dc:creator>catrina</dc:creator>
      <pubDate>Thu, 28 Jun 2018 16:06:54 +0000</pubDate>
      <link>https://dev.to/catriname/using-microsoft-flow-to-sync-basecamp--vsts-to-do-to-tasks-5g3d</link>
      <guid>https://dev.to/catriname/using-microsoft-flow-to-sync-basecamp--vsts-to-do-to-tasks-5g3d</guid>
      <description>&lt;p&gt;We've struggled for years to get various departments to adapt, and stick to, a project management system.  In the past year, have finally had some success with BaseCamp, as it has proved to be user-friendly enough that more and more departments began to use it.  We suddenly needed to adapt to our users.  We needed to make Visual Studio Team Services work with BaseCamp.&lt;/p&gt;

&lt;h1&gt;
  
  
  Make BaseCamp To-Do a VSTS Task
&lt;/h1&gt;

&lt;p&gt;Creating a solution for BaseCamp to VSTS actually proved to be easy enough.  I setup a project in BaseCamp and then a "Main To-Do List".  The only challenge in this is I needed to pass the BaseCamp To-Do Id so that when I closed my VSTS task (work item), it could link back to BaseCamp.  For this, I chose to put the dynamic info in the "tags" field of my VSTS flow.  Here's the setup:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.catrina.me/wp-content/uploads/2018/06/ToVSTS.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.catrina.me%2Fwp-content%2Fuploads%2F2018%2F06%2FToVSTS.png" title="BaseCamp to Visual Studio Team Services" alt="BaseCamp to Visual Studio Team Services"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Tasks
&lt;/h2&gt;

&lt;p&gt;If you notice, the Visual Studio Team Services flow &lt;em&gt;requires&lt;/em&gt; that you select a "work item".  I chose task because it seemed neutral.  I am still able to change it to another type (example: bug), and the sync will still happen as planned.  This is because the flow OUT only links by "work item", "state", and "tag" (BaseCamp Id), not type of work item.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Where Does It Go?
&lt;/h2&gt;

&lt;p&gt;VSTS drops the incoming To-Do as a task in Work Items.  From here, I was able to create a User Story, add it to an iteration, move it along in my KanBan Board as usual.  I kept all the same VSTS work process.&lt;/p&gt;

&lt;h1&gt;
  
  
  Closed VSTS Task Completes BaseCamp To-Do
&lt;/h1&gt;

&lt;p&gt;Flow does have a Visual Studio action for when a work item (any work item: task, bug, etc) to link back to BaseCamp and close the todo.  This is the route I went first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Issues with Current Flow
&lt;/h2&gt;

&lt;p&gt;Unfortunately &lt;em&gt;it does not work&lt;/em&gt;.  Here was how I set it up:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.catrina.me/wp-content/uploads/2018/06/flow_doesnt_work.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.catrina.me%2Fwp-content%2Fuploads%2F2018%2F06%2Fflow_doesnt_work.png" title="Flow Didn't Work" alt="Flow Didn't Work"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt; was not even with the BaseCamp or the Flow idea, &lt;strong&gt;it was that the Flow for VSTS's "work item closed" just would not trigger&lt;/strong&gt;!  I'd do a Flow test, close a VSTS work item and the test would time out, never receiving a trigger!&lt;/p&gt;

&lt;h2&gt;
  
  
  Work Around
&lt;/h2&gt;

&lt;p&gt;What &lt;em&gt;does&lt;/em&gt; trigger is the flow for "work item updated".  So, I replaced the above with "work item updated" and added a condition, checking status for "closed" and then doing my BaseCamp To-Do action.  Here's the work around:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.catrina.me/wp-content/uploads/2018/06/vsts_to_basecamp.png" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fwww.catrina.me%2Fwp-content%2Fuploads%2F2018%2F06%2Fvsts_to_basecamp.png" title="VSTS to BaseCamp" alt="VSTS to BaseCamp"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Flexbility
&lt;/h2&gt;

&lt;p&gt;Again, notice the VSTS to BaseCamp flow doesn't require the item to be a "task".  ANY work item closed will do.  This leaves some freedom to continue to work/organize the way you like in VSTS.&lt;/p&gt;

</description>
      <category>flow</category>
      <category>basecamp</category>
      <category>vsts</category>
    </item>
    <item>
      <title>Print PDF's on Azure Using an API and RazorLight</title>
      <dc:creator>catrina</dc:creator>
      <pubDate>Mon, 11 Jun 2018 15:08:00 +0000</pubDate>
      <link>https://dev.to/catriname/print-pdf-using-a-3rd-party-app-and-razorlight-deploy-to-azure-1453</link>
      <guid>https://dev.to/catriname/print-pdf-using-a-3rd-party-app-and-razorlight-deploy-to-azure-1453</guid>
      <description>&lt;h1&gt;
  
  
  The Problem
&lt;/h1&gt;

&lt;p&gt;I recently had an issue with printing a report to PDF using Microsoft Reporting Service and a RDLC file, etc.  Something similar to &lt;a href="https://docs.microsoft.com/en-us/sql/reporting-services/report-builder/exporting-to-a-pdf-file-report-builder-and-ssrs?view=sql-server-2017"&gt;this&lt;/a&gt;.  Unfortunately, it worked great in development, but refused to work once deployed into Azure.  No matter what I did, I could not duck the GDI errors I kept getting, and apparently this continues through a line of various PDF exporting extensions, all of which rely on GDI for export.  Turns out, &lt;a href="https://www.reddit.com/r/dotnet/comments/8pbflb/html_to_pdf_or_use_pdf_library_for_net_47/"&gt;I'm not alone&lt;/a&gt; in facing this problem and so, I decided to find a solution.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Solution
&lt;/h1&gt;

&lt;p&gt;My general idea was to use something to render my PDF view, send that view as one long html string to this &lt;a href="https://github.com/alvarcarto/url-to-pdf-api?utm_campaign=explore-email&amp;amp;utm_medium=email&amp;amp;utm_source=newsletter&amp;amp;utm_term=weekly"&gt;free PDF microservice by @alvercarto&lt;/a&gt; and get the PDF in return.&lt;/p&gt;

&lt;h2&gt;
  
  
  Render View as HTML
&lt;/h2&gt;

&lt;p&gt;I passed an ID to my PrintAsync function, retrieved it's contents into my view model, but needed to pass that view model into a view, render it, grab it's HTML and send it to the API.  &lt;/p&gt;

&lt;h3&gt;
  
  
  RazorLight
&lt;/h3&gt;

&lt;p&gt;For rendering the model in Razor, I used &lt;a href="https://github.com/toddams/RazorLight"&gt;@toddams RazorLight&lt;/a&gt;. (be sure to use 2.0-beta1 version if you are on Core 2.0)&lt;/p&gt;

&lt;p&gt;It's as easy as declaring a hosting environment variable (used to grab the path of your view).  I created a folder "pdf" under wwwroot for ease of access:&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;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IHostingEnvironment&lt;/span&gt; &lt;span class="n"&gt;_hostingEnvironment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instantiate it in the constructor:&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="n"&gt;_hostingEnvironment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hostingEnvironment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and use that to bring in your web root path.&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RazorLightEngineBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
              &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseFilesystemProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_hostingEnvironment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebRootPath&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"\\pdf\\"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseMemoryCachingProvider&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
              &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&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;view&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;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CompileRenderAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PDF.cshtml"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;invoiceVM&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Notes on the View
&lt;/h3&gt;

&lt;p&gt;Take special note on how you set up your view.  No need to pass the model up top, and to make the path of my layout file easy, I just dropped it in same folder as my PDF view.  Also notice how it just refers to @Model.  Here's a snippet from my PDF view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@{
    Layout = "CleanLayout.cshtml";
}
&amp;lt;div class="container"&amp;gt;
    &amp;lt;div class="columns"&amp;gt;
        &amp;lt;div class="column"&amp;gt;&amp;lt;b&amp;gt;Invoice Date: &amp;lt;/b&amp;gt;@Model.InvoiceDate&amp;lt;/div&amp;gt;
        &amp;lt;div class="column"&amp;gt;&amp;lt;b&amp;gt;Account #: &amp;lt;/b&amp;gt;@Model.Account&amp;lt;/div&amp;gt;
        &amp;lt;div class="column"&amp;gt;&amp;lt;b&amp;gt;Invoice #: &amp;lt;/b&amp;gt;@Model.InvoiceNumber&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pass to API and Get Bytes to PDF
&lt;/h2&gt;

&lt;p&gt;Now that I had the HTML string I needed, I was easily able to create a JSON request and post to the api:&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;httpWebRequest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpWebRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;WebRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://url-to-pdf-api.herokuapp.com/api/render"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//2cm margins with emulateScreenMedia for css&lt;/span&gt;
&lt;span class="n"&gt;httpWebRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentType&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;httpWebRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Method&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"POST"&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;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;emulateScreenMedia&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;margin&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;top&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"2cm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                        &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2cm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                        &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2cm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                        &lt;span class="n"&gt;bottom&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2cm"&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;asJson&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;JsonConvert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SerializeObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;using&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;streamWriter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;httpWebRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetRequestStream&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;streamWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;asJson&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;streamWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Flush&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;streamWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Close&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;This was successful, the only problem being the httpresponse returns in bytes and needs to be saved as a PDF file.  Here's that solution:&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="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;httpResponse&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpWebResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;httpWebRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetResponse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;objStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;httpResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetResponseStream&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;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;objStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"application/pdf"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, I simply have a print button to call this method:&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="n"&gt;@Html&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ActionLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Print Claim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"PrintAsync"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;@class&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"button is-info"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploying onto Azure, I got a Microsoft.Win32 error, so I had to add this to my .csproj file:&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;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MvcRazorExcludeRefAssembliesFromPublish&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;MvcRazorExcludeRefAssembliesFromPublish&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And done!  Of course, I still gotta work on the styling, margins of PDF, but it was enough to get started.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>azure</category>
      <category>pdf</category>
    </item>
    <item>
      <title>Windows 2012 Server – Time Out of Sync</title>
      <dc:creator>catrina</dc:creator>
      <pubDate>Wed, 16 May 2018 15:24:28 +0000</pubDate>
      <link>https://dev.to/catriname/windows-2012-server--time-out-of-sync-1157</link>
      <guid>https://dev.to/catriname/windows-2012-server--time-out-of-sync-1157</guid>
      <description>&lt;p&gt;Our help desk guy is on vacay, Server Admin on the road and I'm last in our little team.  So, there's this awkward "documentation" post.&lt;/p&gt;

&lt;p&gt;Our “TimeClock” server (of all servers!) became 5 minutes out of sync. I used a 3rd party time server, &lt;a href="http://www.pool.ntp.org"&gt;NTP Pool Project&lt;/a&gt; to solve the problem. Here’s how:&lt;/p&gt;

&lt;p&gt;Open CMD prompt as admin, and set time sync to 3rd party server using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;w32tm /config /syncfromflags:manual /manualpeerlist:"0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source: &lt;a href="http://www.pool.ntp.org/en/use.html"&gt;http://www.pool.ntp.org/en/use.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open Server Manager Tools Services&lt;br&gt;&lt;br&gt;
Select “Windows Time”&lt;br&gt;&lt;br&gt;
Restart&lt;/p&gt;

&lt;p&gt;Return to CMD prompt and enter:&lt;br&gt;&lt;br&gt;
&lt;code&gt;w32tm /query /status&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;All is groovy and back in sync!…&lt;/p&gt;

</description>
      <category>helpdesk</category>
      <category>windows2012server</category>
    </item>
    <item>
      <title>Let's Build</title>
      <dc:creator>catrina</dc:creator>
      <pubDate>Mon, 14 May 2018 05:01:31 +0000</pubDate>
      <link>https://dev.to/catriname/lets-build-14cc</link>
      <guid>https://dev.to/catriname/lets-build-14cc</guid>
      <description>&lt;h2&gt;
  
  
  New Environment, New Approach
&lt;/h2&gt;

&lt;p&gt;It's Day 1, my first Microsoft Build, and I was not prepared for the sheer numbers nor format.  I tediously worked out this schedule with sessions and back up sessions (in case, I don't know… tripped on the way to the first one?).  I lost my OCD mind when I realized these sessions were held open format in the MIDDLE OF THE EXPO!&lt;/p&gt;

&lt;p&gt;I quickly realized the "sessions" were to show off their specialty.  To draw you in by topic, touch on some "new" topics you hadn't heard of, and get you to come talk to them.  The presentation was not so much a sales pitch as it was a "let me help you develop on our platform."  Interesting...&lt;/p&gt;

&lt;h2&gt;
  
  
  My Problem
&lt;/h2&gt;

&lt;p&gt;When I decided to learn C# and .NET a couple of years ago, there was a lot of circling the drain, BUT it gave me some ideas.  One of those ideas was the creating my own API to open up the iSeries and automate our payment system.   In doing that, I stopped a lot of frustration in interacting with the legacy system and freed myself to move forward.&lt;/p&gt;

&lt;p&gt;Now, though, I've quickly realized I chose to move forward with a bleeding edge platform with a small beginner community.  Either you've been on .NET framework and weary of moving to Core, or you're on Core (like me) and still working things out (or worked it out and write the docs).&lt;/p&gt;

&lt;p&gt;When I ask for help I either meet that level's boss and immediately resurrect my "imposter syndrome", or I drown the person I am asking and they send me some link I've already seen 20 times.  &lt;/p&gt;

&lt;p&gt;This leaves me with lots of projects or goals that are missing parts or just plain "stuck". &lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Un-Stuck
&lt;/h2&gt;

&lt;p&gt;I approached Day 2 with one goal:  get "unstuck". I have access to the experts… get out there, find their booth and ask!&lt;/p&gt;

&lt;p&gt;Some of my "stuck" problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I can't figure out why my "print to pdf" function works in development but not on Azure&lt;/li&gt;
&lt;li&gt;I can't figure out how I, a 1 person team, involves the end-user to create a more accurate work-flow (VSTS) without making them do weird, techy things&lt;/li&gt;
&lt;li&gt;I do not have an accurate "feedback" system once my app is launched&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Yes, I found some answers / leads:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I am not alone.  I was given an expert email/contact for help (GDI problem) and also suggested it might be a 3rd party extension to solve this.&lt;/li&gt;
&lt;li&gt;I was shown a template feature I never knew of that basically emails an employee/department a form that they fill out in Outlook.  It emails me back and creates a "work item" for me.&lt;/li&gt;
&lt;li&gt;I was shown an "Insider" program that helps me create my own set of power users (dealers) that I can launch features to and get feedback from.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I'll have to take time to learn how to do all these things, but, it's room for positive growth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Planning for the Future
&lt;/h2&gt;

&lt;p&gt;Day 3, I made it my focus to go to the booths I had been avoiding.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does this random sponsor company do?&lt;/li&gt;
&lt;li&gt;What part of tech in Microsoft are you?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hate sales pitches and I was very upfront about what I do, what I work with and what I needed.  If they did not meet my needs I was quick to say so, but I was also very happy with them and clear I was there to collect info.  &lt;/p&gt;

&lt;p&gt;I have to keep in mind, at one point I thought I'd never have a need for a fancy "API".  Years later, that little nugget in the back of my head solved a huge problem of ours.  So, this was the day I took to just listen.  Let them show you something and put that in your head for later.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Work Isn't that Different
&lt;/h2&gt;

&lt;p&gt;A jewel I really adored walking away from a conference of developers was seeing how we work.  &lt;/p&gt;

&lt;p&gt;The most popular drinks gone were my faves (Coke Zero, Sparkling water), everyone had a water bottle hanging off their bag, low carb snacks, meditation room, coloring books, animals, "quiet" charging lounge.  By day three people were walking around in socks (lots and lots of walking at this).  All of the above are regular habits of mine and it was refreshing to see the community is recognizing health as a high priority.  Yes, I rarely take lunch.  Yes, my focus often makes me forget normal tasks.  I sit for too many hours in a day.  Developers are not alone in this, but as a professional community, it was refreshing to see steps forward in maintaining physical health as a way toward professional growth.&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>dotnet</category>
      <category>build</category>
    </item>
  </channel>
</rss>
