Sunday, September 30, 2018

how not to do database initialization strategies with Entity Framework

Page 175 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis discusses the database management patterns/database initializers/DbInitializers of the early Code-First flavors of Entity Framework before version 7, what is being referred to as EF Core. Out of the box there were four of these:

  • CreateDatabaseIfNotExists
  • DropCreateDatabaseIfModelChanges
  • DropCreateDatabaseAlways
  • MigrateDatabaseToLatestVersion

 
 

Anymore all database initialization stuff is done with PowerShell commands and there are few C# commands. There are three right on the DbContext like so...

  • Database.EnsureCreated()
  • Database.EnsureDeleted()
  • Database.Migrate()

 
 

...but the book eludes to these not being the main focus. I don't know if it will even circle back to them. I'm expecting to be working in PowerShell. Anyways, the four database management patterns/database initializers/DbInitializers could all be inherited from and then extended by way of overriding methods. The book suggests that they were bad because they required a hardcore geek level of knowledge of Entity Framework that was not inclusive to anyone trying to just get their feet wet. From my own experience I found the showstopper for Code First stuff to really lie in this pain point too. I guess the next few pages ahead will allow me to form an opinion as to whether or not anything has gotten better.

Saturday, September 29, 2018

Eden Prairie's Teque Arepa is my new favorite restaurant.

A one-of-a-kind Venezuelan restaurant run by a Venezuelan family, the venue is a welcome addition to a city full of strip malls and chain stores. So far this is the most offbeat thing I have found in generic Eden Prairie. (A coworker recommended it.)

Teque Arepa offers Arepa, a Venezuelan dish of many shapes I had not heard of before. Basically you cut a muffin into the two "bread slices" of a little sandwich and you put something hot and wonderful inside. The dishes here are number 113 Catira Hot (left) and number 106 Pabellón (right) with the beef option.

The wealth of Arpea variants is rivaled by a wealth of smoothie variants. I guess we have some America creeping in with the Venezuela in that regard. My smoothie is a strawberry smoothie.

Why not try it for yourself? It is at 7733 Flying Cloud Drive in Eden Prairie, Minnesota. The zip code is 55344. It's in a strip mall so there must be a suite number, but I can't find it in Googling for it. You'll see it.

Set up a DbContext for the Entity Framework's Code First stuff.

Keeping with the Foo and the Bar object here I think we could have:

using Microsoft.EntityFrameworkCore;
using OurStuff.Data.Models;
namespace OurStuff.Data
{
   public class OurDbContext : DbContext
   {
      public DbSet<Foo> Foos { get; set; }
      public DbSet<Bar> Bars { get; set; }
      
      public OurDbContext(DbContextOptions options) : base(options)
      {
         
      }
      
      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
         base.OnModelCreating(modelBuilder);
         
         modelBuilder.Entity<Foo>().ToTable("Foos");
         modelBuilder.Entity<Foo>().Property(f => f.FooId).ValueGeneratedOnAdd();
         modelBuilder.Entity<Foo>().HasMany(b => b.Bars).WithOne(f => f.Foo);
         
         modelBuilder.Entity<Bar>().ToTable("Bars");
         modelBuilder.Entity<Bar>().Property(b => b.BarId).ValueGeneratedOnAdd();
         modelBuilder.Entity<Bar>().HasOne(f => f.Foo).WithMany(b => b.Bars);
      }
   }
}

 
 

This comes from pages 173 and 174 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis. Do note the pluralized names for would be database tables. This has forever been the EF way while NHibernate geeks would just have a Foo table for the Foo object.

I saw Luke Schlangen speak at JavaScript MN on Wednesday night on deployments.

Some interesting things were name dropped. GatsbyJS is a React-based tool that allows one to build static web sites quickly. Hugo and Jekyll are other, rival static site generators. Netlify at https://app.netlify.com/ is an intriguing environment where you may quickly host such a site. You may just drag and drop files into the web interface to get them online. You can name a project and Netlify will make a ceremonial little convenience URL for your web site. What is more, if you point the A record for a domain name to Netlify you can, yes, have your domain name resolve to the off-the-cuff hosting and have a real web site by anyone's definition. Maybe this is the new GeoCities, eh? If you don't create an account at Netlify your creations will only last a day, but if you create an account your hosting will be ongoing. Luke opined about how he had packed a bunch of stuff onto Netlify's platform and that they were nonetheless yet to reach out to him for a credit card number or to suggest any sort of payment plan. Another chunk of this talk went into Firebase. "What is the cloud? It's someone else's computer." (Luke verbatim.) We goofed off with Heroku some too. You can't push a Node server up to Firebase or Netlify but in both cases the workaround is to use Google Cloud Functions. These are going to be just what they sound like, some sort of function "out there" that you call out to and get something back from. I don't know how canned versus customizable they are. GitHub Pages is another service for hosting simple static stuff. Luke said that he shied away from using it in his live coding demo as it can take five minutes for your deployments to appear online. Google's Lighthouse will audit your web site and give you performance metrics on how heavy or snappy it is. Matt boasted of how he could get a metric of 90 for one of the simple sites he spun up while google.com itself had a mere 89. Scratch is a very visual scripting language for kids and there is a Scratch IDE. The Scratch IDE, which is web-based, was run through Lighthouse to show off of an example of a performance monster that is going to be judged very harshly by Lighthouse. What else is there to say? Before Luke Schlangen (rightmost in the photo, being introduced by Brandon Johnson) spoke a Terrance Schubring gave a lightning talk on a React component that he had baked. The venue for JavaScript MN has moved to a locale called space150 and this was the first go in the space150 office. The turnout seemed pretty robust in spite of the shakeup.

Friday, September 28, 2018

OpenTextFile in Classic ASP and how to make it "safe" for HP Fortify

This kinda suggests that second, third, and fourth variables may be handed in to restrict the scope of what this can do. The first just specifies the name of the file. The third variable is a true or false variable and handing in false will prevent new files from being created it would seem.

 
 

Addendum 10/5/2018: The better way to go may be to wrap the first variable in mappath(yournamehere) actually.

encrypted stored procedures

This is a thing! You may host databases crafted by third parties that have stored procedures that you cannot read even though it is you that are hosting them.

What is the WebClient of C# 4.0?

It is a kinda ghetto way of hitting API endpoints before the async/await stuff of C# 5.0. The code below is synchronous and just hangs out until we round trip to someone else's server or blow up in exception.

using System.Net;
using System.Text;
using RefreshCerts.Core.ExternalDependencies;
using RefreshCerts.Core.Objects;
namespace RefreshCerts.Infrastructure.ExternalDependencies
{
   public class ApiInteraction : IApiInteraction
   {
      public string GetToken(Bootstrapping bootstrapping)
      {
         using (WebClient webClient = new WebClient())
         {
            webClient.Headers.Add("Content-Type", "application/json");
            var response = webClient.UploadData(bootstrapping.ApiUrl + "authorize",
                  "POST", Encoding.Default.GetBytes("{\"Username\": \"" +
                  bootstrapping.ApiUsername + "\", \"Password\": \"" +
                  bootstrapping.ApiPassword + "\"}"));
            string token = Encoding.UTF8.GetString(response);
            return token;
         }
      }
   }
}

 
 

Honestly, I may abandon this approach and this may be the only blog posting on this subject. I think I went down the wrong rabbithole. Anyhow, some pain points I hit included this error:

The Content-Type header cannot be changed from its default value for this request.

 
 

The fix for this per this is to include the line above that has "application/json" in it. Another error I hit in orginally trying to craft code like this was:

The remote server returned an error: (415) Unsupported Media Type.

 
 

This came from using an .UploadValues implementation instead of an .UploadData implementaion. In .UploadValues the first two parameters handed in are the same (a URL and a verb) and the third is an object like our stuff object here:

var stuff = new NameValueCollection();
stuff["Username"] = bootstrapping.ApiUsername;
stuff["Password"] = bootstrapping.ApiPassword;

 
 

Alright, on the otherside of the two errors above I get:

The remote server returned an error: (403) Forbidden.

 
 

...but that just means my username and password are wrong.

Thursday, September 27, 2018

parent/child Code First Entity Framework relationships

Pages 171, 172, and 173 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis touch on how to wire-up one-to-many constraints between Code First objects for Entity Framework. The de facto way to go seems to allow parent objects with collections to lazy-load the collections. They don't get loaded until first "touched" (accessed) so to speak. If a Foo has n number of Bars then the Bar POCO has an auto-property like so to tie back to its Foo like so:

[ForeignKey("FooId")]
public virtual Foo Foo { get; set; }

 
 

That's a Foo named "Foo" y'all! You will need the System.ComponentModel.DataAnnotations.Schema namespace looped in. This use of the virtual keyword blows my mind. I guess it makes both the get and the set virtual. The whole point of having getsetters (well, auto-property anymore), as best as I can tell, is to gold plate in the possibility for some polymorphism that ain't gonna happen 99 times out of 100 in flagrant disregard for the YAGNI principle. We somehow fell in love with this as developers and now having just a public variable of a specific type at a POCO seems strange while getsetters are... So Fetch! What do you do with a getsetter that does not have the virtual keyword? How do you rationalize it? I suppose it empowers method hiding distinctions from child to parent for the get and the set. I digress. Anyways, at Foo we have:

[Key]
[Required]
public int FooId { get; set; }
 
public virtual List<Bar> Bars { get; set; }

Dynatrace Appmon

Appmon collects transactions into what are known as PurePaths and you may drill into each transaction at a Dynatrace dashboard. In monitoring databases you may see every query run and when it was run and drill in to get performance metrics like how long it took and I guess how much it challenged memory available, etc. You can do similar transaction montioring for code too.

See the history of notifications on the iPhone X.

When you drag a finger upwards to unlock your phone and punch in a PIN, just drag up from the middle of the screen instead of the base of the screen. As tricky and elusive as this may seem, you don't have to be a Harvard graduate like Bill Gates or Mark Zuckerberg to see the notifications. er, well... wait...

Use .CompareTo in C# to compare two strings in two different lists while looping through each list only once!

private static List<Certificate> FilterCertificates(Bootstrapping bootstrapping)
{
   List<Certificate> filteredCertificates = new List<Certificate>();
   List<Certificate> certificates = bootstrapping.CertificateAuditing.Audit(bootstrapping)
         .OrderBy(x => x.Name).ToList();
   if (bootstrapping.CertificatesWhichMeritAttention.Length == 0) return certificates;
   int counter = 0;
   foreach (string certificateWhichMeritsAttention in
         bootstrapping.CertificatesWhichMeritAttention)
   {
      bool isVetted = false;
      while (!isVetted)
      {
         if (counter >= certificates.Count)
         {
            isVetted = true;
         }
         else
         {
            int comparison = certificates[counter].Name.ToLower()
                  .CompareTo(certificateWhichMeritsAttention.ToLower());
            if (comparison < 0)
            {
               counter++;
            }
            if (comparison == 0)
            {
               filteredCertificates.Add(certificates[counter]);
               counter++;
               isVetted = true;
            }
            if (comparison > 0)
            {
               isVetted = true;
            }
         }
      }
   }
   return filteredCertificates;
}

 
 

Per this the string comparison will compare each string a character at a time. Therefore, I think the .ToLower() stuff has to get mixed in as, as noted here, a lowercase a has a greater numeric ASCII code than a capital B which has a lower numeric ASCII code than a lowercase c. Clearly we could have just done this instead:

private static List<Certificate> FilterCertificates(Bootstrapping bootstrapping)
{
   List<Certificate> certificates = bootstrapping.CertificateAuditing
         .Audit(bootstrapping).OrderBy(x => x.Name).ToList();
   if (bootstrapping.CertificatesWhichMeritAttention.Length == 0) return certificates;
   List<Certificate> filteredCertificates = certificates.Where(x => bootstrapping
         .CertificatesWhichMeritAttention.Contains(x.Name)).ToList();
   return filteredCertificates;
}

 
 

Clearly that might make for more maintainable code. The big question is "Do we fear a performance hit (as suggested here) in a Big O puzzle?" as the shorter code will loop one of the lists once (perhaps not a full time, perhaps just until a match is made if a match is made) for every item in the other list and thus comes with more of a performance hit.

Wednesday, September 26, 2018

Nightwatch.js

It is an end-to-end (E2E) testing-at-the-browser testing tool like Selenium that ultimately uses Selenium. This one is Node.js based. The syntax is different than that of Selenium. I guess you are writing in JavaScript and not Groovy. While I am thinking of this stuff Watir stands for Web Application Testing in Ruby and WatiN for Web Application Testing in .NET along the same lines.

Tuesday, September 25, 2018

Get all of the names of all of the files in a directory with C#.

An example and a pratical application:

public void DeleteOldLogsToAvoidMemoryLeaks(Bootstrapping bootstrapping)
{
   foreach (string filePath in Directory.GetFiles(bootstrapping.LogDirectory))
   {
      string[] filePathParts = filePath.Split('\\');
      string fileName = filePathParts[filePathParts.Length - 1];
      if (fileName.Length > 3)
      {
         string fileNamePrefix = "" + fileName[0] + fileName[1] + fileName[2] + fileName[3];
         if (fileNamePrefix != bootstrapping.Timekeeping.GetDate().Year.ToString())
         {
            string[] fileNameParts = fileName.Split('.');
            string extension = fileNameParts[fileNameParts.Length - 1];
            if (extension == "txt")
            {
               File.Delete(filePath);
            }
         }
      }
   }
}

 
 

I got the name from this which also suggests that there is a Directory.GetDirectories beyond Directory.GetFiles and that one may use the strings from Directory.GetDirectories to turn around and crawl for file names one folder deep with Directory.GetFiles and getting creative a bit one may thus recursively make a list of all files in all folders from a topmost folder downward.

I took an Agile assessment today and some terms I had not heard were name dropped.

  • Just as a velocity is measured in points a capacity is measured in hours.
  • A Program Increment (PI) Plan in SAFe is basically like the length of a sprint in Scrum. This also has the terms PDCA for Plan, Do, Check, Adjust wherein the Adjust step encompases I&A (Inspect and Adapt) and Agile Release Train (ART) which seems to be ongoing development cranking out deliverables. The same link above also suggests in SAFe there is typically a Innovation and Planning (IP) Iteration after perhaps four consecutive PI interations.
  • Stories should be demonstrable and end-to-end functionality as a term suggests this.
  • The INVEST model stands for Independent, Negotiable, Valuable, Estimate-able, Small, Testable and per Bill Wake a good Product Backlog Item or PBI has these qualities.
  • When we "track progress" we have a burndown chart.
  • The impediments are anything slowing down a team.
  • Work-In-Process (WIP) limits have to do with breaking stories out into swimlanes so others can see at a glance how a story is progressing.
  • Definition of Done (DoD) is what it sounds like and varies. This has a done/done/done/done definition wherein the four dones are coded, verified (unit tested), validated (product owner approves), and production ready.
  • RTE stands for Release Train Engineer and this guy reports to a product owner and oversees the scrum masters leading various scrums.
  • To jump from "planning to designing to coding to testing to finishing" per Vin D'Amico here is swarming.
  • What is more, ephemeral the English language word means lasting for a short time while holistic the English language word suggests that wherein the whole is more important than the pieces.

Nintex lives!

To my surprise Minnesota has a Nintex meetup group! See this! A write up from the next meeting includes: "Nintex vTE Ben Stori will discuss the difference between bound data and unbound data within Nintex forms and how to get unbound data out of Nintex Forms using Nintex Workflow." vTE is virtual Technical Evangelist. Based on this it looks like unbound data is data that does not tie directly back to a SharePoint column. My thoughts can imagine scenarios... a datapoint that sets two columns... a which-way-to-I-go decision in a workflow that does not get ultimately saved...

Monday, September 24, 2018

EDI file formatting standards for medical recordkeeping

An EDI file will start out with ISA* and end with something like...

GE*1*129768013~
IEA*1*129768013~

 
 

Between this header and footer there will be individual records, sometimes one per file or sometimes with numerous records per file. All records starts out with ST* followed by an integer and end with SE* followed by an integer and eventually the next tilde. The number after ST* denotes the type of record. ST*834 is for members for example while ST*837 is for claims. The number after the SE* denotes a total number of rows of data between the ST* and the SE* for the record which is sort of like a record set honestly. Members and claims are pretty much industry standard terms in the healthcare insurance space. Members (which make doctor visits while holding insurance) have claims which get graded in an adjudication process. Clients have members insofar that employers (businesses) have employees. The clients are the employers and the members the employees. Providers are doctors' offices. Different insurance plans are referred to as groups and a group will encircle n number of members and denote what providers they may use, i.e. answering the question: Is a provider in group? The domain, as Eric Evans might whiteboard it out, is already halfway congealed.

PeSIT

Invented by French Interbank Teleclearing System Economic Interest Grouping (GSIT) in 1986, PeSIT stands for Protocole d'Echange du Système Interbancaire de Télécompensation meaning "Inter-bank electronic payment system protocol" and is file transfer protocol like FTP (File Transfer Protocol) only this one is supposedly better at ISO/OSI wherein ISO is International organization of Standardization and OSI is Open Systems Interconnection. This is the protocol Axway uses to transfer files.

Aperture is the name of the UI dashboard portal for Venafi.

This is the new user interface. VEDAdmin was the name for the old way to go.

 
 

Addendum 9/25/2018: VED stands for Venafi Encryption Director and Wikipedia suggest that Venafi the name comes form the Latin words Vena for vein/root and Fides for trust/faith. The venafi.com website has a whitepaper in the shape of a "For Dummies" book advertised at the home page to help you get your head around their security stuff!

F5 Networks offers the F5 device for load balancing.

Their product line has expanded beyond just the load balancer in modern times. Business continuity and disaster recovery plans are some buzz words I found at their web site, etc.

Sunday, September 23, 2018

Angular's Achilles' heel

I found myself thinking last night of the problem in Angular that is the form validations and the puzzle of what to do as suggested here. My incel (involuntary celibate) acerbic persona has no children as this is what I do with my time on the weekends. It's probably best that I'm a programmer instead of a project manager or scrum master or something. Anyhow, I wrestle with whether or not it is best to serialize a set of validation rules and hand them over the wire from the headless app to the Angular frontend as there is a performance hit with that. I'm leaning towards concluding that this information should just come once and then get cached. I hate the idea that it would only exist in the UI as the UI is really a different app and that would mean that the main app would have no idea of how to validate itself. That might be fine but my mind fights it. It seems like rulesets for what is sane are part of the core logic in Onion Architecture. I guess you can break with the DRY principal and write validations in both places. Honestly, as it is we are writing dupes for C# side POCOs that make their way into TypeScript and the TypeScript classes their object instances map to. This talk touched on trying to fix the bigger duplicate code maintenance problem but I don't recall it mentioning the validations and there is probably not support for that. You don't want to roll your own code generation implementation as other developers will hate you when they follow your work and deal with the thing you thought was awesome that isn't really awesome. Don't get creative.

vlog is a video blog

I saw the movie "A Simple Favor" and the term was used a lot.

Friday, September 21, 2018

reversing a list in C#

It's really a lot like reversing an array in either C# or JavaScript honestly.

List<string> endCap = new List<string>(){ "Z", "Omega" };
endCap.Reverse();

ViewState XSS attack

Why not attack web forms applications by handing in your own value for ViewState which is just passed around as a hidden type input? When the encrypted stuff gets unencrypted... surprise! I'm not sure what to do about this yet. Per this you may prevent a CSRF (cross-site request forgery) attack by checking against something kept in Session. I guess you can also try to look at who bumped into you at a web form's code behind like this:

System.Uri whereWasI = Request.UrlReferrer;
string whereExactlyWasI = whereWasI.OriginalString;

 
 

cheesy/sleazy

What is a web method at web forms?

It is for ghetto web services. This has this example:

[System.Web.Services.WebMethod]
public static string search()
{
   return "worked";
}

 
 

To hit this from JavaScript you would call out to the URL of your .aspx page and chase the URL with "/search" on the end. That should let you pull the "worked" out into the JS implementation via AJAX. The same StackOverflow thread I reference above suggests you need a ScriptManager and that EnablePageMethods="true" should be an inline parameter in the ScriptManager.

static sabotage

When attempting this sort of threading with messaging by actions back to the UI, I don't think one may use static methods for the actions out of static utility classes that get loaded on the main/root thread. I have experienced some errors wherein I am told that I cannot update a WinFroms control because the wrong thread is accessing it and all I can think of in what could be going wrong is that I have drilled into a method with a signature of static async void and have tried to call out to an action handed in at the signature from inside. I don't see what another variable might be.

I thought today of Anshu Jain saying "I saved us 20 tables" or however many while I was at FramesDirect.

Basically he had a settings table with a column for which pseudotable each row corresponded to. This was to sidestep a bunch of "little tables" and reduce database noise. I also remember him explaining to me that we were keeping all of our C# classes in the App_Code folder because framesdirect.com had to be up and making sales 24 hours a day and if we just updated one or two classes at a time in an update it would better than updating the whole of a .dll as it would be less likely to break a sale that was midstream in process. What a mess. Mamie Jones left right after I did and Ravi Meta followed her. Benoit Baudon de Mondy left when I did. Clotilde Bedoya was there for quite a while after. Some of the Anshu revelations above occurred before I started keeping this blog. (I started it at FramesDirect.) Anyhow, I'll try not to write of things older than this 7+ year old blog anymore. I'll try not to live in the past. Going forward I will only write of things that have occurred since I've moved to Minnesota. I'll try to look to the future.

X-Frame-Options

As an HTTP header this attempts to restrict the use of the content in an iFrame! I don't see how this magic could work. Maybe it only behaves itself in newer browsers that look for the header. DENY as an option here prevents the use of the page in an iFrame outright while SAMEORIGIN allows the same site to have iFrames to itself more or less. ALLOW-FROM lets one spec a list of URLs for acceptable "framers" so to speak.

XFS is Cross Frame Scripting

This is the subset of Cross-site scripting (XSS) attacks that use an iFrame out to elsewhere to do awful, awful things.

Try casting a magic string past as a GET variable to be used in a switch/case statement to an enum?

This could be smart in the name of improving security on something in C# (think web forms) that was bad to begin with. Instead of trying to strip sinister characters out of the string to make it safe, why not restrain it to one of only a handful of legitimate shapes?

Thursday, September 20, 2018

ESI (Edge-Site Includes)

If you have a tag in HTML like so:

<esi:include src="/shopping_cart" />

 
 

...and it passes through some ESI server/service that knows what to do with the ESI markup, this tag, which is otherwise illegitimate as HTML, can be replaced with something competent. That tends to be data sucked down from another web source. A reverse proxy middleman can do these sorts of manipulations.

HTTP compression is a thing

Accept-Encoding: gzip, deflate ...for example as a convention in a header of an HTTP request communicates what is acceptable and expected in terms of tooling for a decompress. The point of the compression is to make the package smaller and thus quicker.

Tshirt sizes in Lean/Kanban are trending.

The whole point of the Lean thing is not to have estimates for points like Scrum has right? We are not going to have a burndown chart and tell the stakeholders: "Look, we have to make some sacrifices given this velocity." We are just going to work on the tasks we have to do anyways and it doesn't really matter how long it takes as we have to charge forward. This is more the thing of a product company doing maintenance and improvements than a consultancy trying to insulate itself from having to eat the costs of scope creep. That said, a gut estimate of whether something is a small, a medium, a large, an extra large, etc. is helpful. T-shirt sizes of this shape have crept into the process apparently. There is no reason to do specific estimates as estimates are always wrong so let's just have tee shirt sizes instead of points. They are a gut feeling just so that everyone knows what is going on. When you screw up one of these estimates there should really no consequences honestly.

Getting a subset of a list in C# is a lot like getting a substring.

This should pull the 4 and the 5 below out into its own list.

List<int> eight = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8 }
List<int> crazy = eight.GetRange(3, 2);

A simple modern way to cast an array of bytes to a string in C#.

byte[] bytes = goGetStuff();
string result = System.Text.Encoding.UTF8.GetString(bytes);

Delete a file with C#!

using System.IO;
using MyOwnStuff.Core.Interfaces;
namespace MyOwnStuff.Infrastructure.ExternalDependencies
{
   public class FileRemoval : IFileRemoval
   {
      public void Destroy(string filePath)
      {
         File.Delete(filePath);
      }
   }
}

Wednesday, September 19, 2018

Clickjacking

This can be defined as any sort of hack with sinister clickbait or perhaps alternatively a hidden second action or overpowering action when one clicks on something legit. This is HTML injection stuff. It looks like I am back to going through the .fpr files that both HP Fortify and HP WebInspect make and looking into the Critical, High, Medium, and Low issues.

the very specific name ApplicationUser

Ever the technocrat, Valerio De Sanctis suggests on page 163 of his book "ASP.NET Core 2 and Angular 5" that ApplicationUser is by naming convention the best name for a class that inherits from IdentityUser, a base class used by the ASP.NET Identity module. There probably will only be the one class, eh? He has an example of a POCO class for ApplicationUser on pages 162 and 163 and it uses attributes driven by System.ComponentModel.DataAnnotations at what would otherwise seem an innocuous plain Jane class to start out with. Ultimately, this is going to be an Entity Framework Code First class however. Some of the getsetters with the annotations look like so:

[Key]
[Required]
public string Id { get; set; }
 
[Required]
[MaxLength(128)]
public string UserName { get; set; }
 
[Required]
public string Email { get; set; }

 
 

Addendum 9/20/2018: The annotation [DefaultValue(0)] would be for a default value of zero I suppose.

 
 

Addendum 9/23/2018: DefaultValue is in the System.ComponentModel namespace not the System.ComponentModel.DataAnnotations namespace.

Tuesday, September 18, 2018

How may I read from a flat file that is more than 2 Gigs in size in C#?

The only way to do this is to do so in chunks. I would recommend rewriting the flat file to a series of smaller flat files and then doing some operations with two chunks at a time to deal with breaks in XML formatting or other lack-of-a-clean-break dirtiness between the chunks that may arise. Below is some logic for breaking up a file into smaller files based on this.

public async void DivideAndConjure(InitialDetails initialDetails, Action<Alert> alertAction,
      long length)
{
   try
   {
      int shortLength = (int)Math.Ceiling((decimal)length / 26);
      string[] pathParts = initialDetails.FromPath.Split('\\');
      string[] nameParts = pathParts[pathParts.Length - 1].Split('.');
      string stringFormat = initialDetails.ToPath + "\\" + nameParts[0] + "{0}." +
            nameParts[1];
      for (int counter = 0; counter < 26; counter++)
      {
         char character = (char)(65 + counter);
         string toPath = String.Format(stringFormat, character);
         await Task.Run(() => { Write(initialDetails.FromPath, alertAction, counter,
               shortLength, stringFormat, toPath); });
         alertAction(new Alert(String.Format("Temp file written to: {0}", toPath),
               TypeOfAlert.Success));
      }
      alertAction(new Alert(String.Format("{0} has been chunked to: {1}",
            initialDetails.FromPath, initialDetails.ToPath), TypeOfAlert.Success));
   }
   catch (Exception exception)
   {
      alertAction(new Alert(exception));
   }
}

 
 

You have to break the writing of the individual chunks out onto a separate thread for each or else the process will crash partway in the same way it would if you just tried to read a file that is too big. Below is my subtask and do also note the casting to an Int64 type below. Without the casting, I was getting weird errors about how I should be using a positive number instead of a negative number and this was due me counting an Int32 variable so high that it past its upper bounds and then lapped into the lower bounds of its range. Wacky!

private void Write(string fromPath, Action<Alert> alertAction, int counter, int shortLength,
      string stringFormat, string toPath)
{
   try
   {
      byte[] bytes = new byte[shortLength];
      using (FileStream inStream = new FileStream(fromPath, FileMode.Open,
            FileAccess.Read))
      {
         inStream.Position = (((Int64)shortLength) * counter);
         inStream.Read(bytes, 0, shortLength);
      }
      using (FileStream outStream = new FileStream(toPath, FileMode.Create,
            FileAccess.Write))
      {
         outStream.Write(bytes, 0, bytes.Length);
      }
   }
   catch (Exception exception)
   {
      alertAction(new Alert(exception));
   }
}

 
 

You may realize that with the Math.Ceiling trick that the numbers may not line up so nicely for the Z slice. That's alright. It's always alright to overshoot the size of a bytes array when you are hydrating it in these file slurping acrobatics. That won't throw an error or hurt anything. The file that gets written won't be sick.

Read off the length in bytes of a flat file in C#.

public long GetFileLength(string x)
{
   using (FileStream fileStream = new FileStream(x, FileMode.Open, FileAccess.Read))
   {
      return fileStream.Length;
   }
}

Monday, September 17, 2018

The file is too long. This operation is currently limited to supporting files less than 2 gigabytes in size.

This error rears its head when you'd expect in C#. I got it from the following code.

public Byte[] SimpleRead(string fromPath)
{
   return File.ReadAllBytes(fromPath);
}

Three Types of Entity Framework?

Pages 157 to 161 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis have a pretty good breakdown. Model-First is the old way of doing things with an .edmx. EDMX stands for Entity Designer Model XML visual interface and the book also name drops XML-based DataSet Schema and gives the acronym XSD though I suspect that is yet another typo in the book and that XDS is meant. I guess the XDS files are the XML mapping files the .edmx makes as you model stuff with it. In the Database-First approach we build a database and then let everything else autogenerate reactionarily off of that including, to my surprise, an .edmx by way of what the book suggests is the Entity Framework Designer tool. In the Code-First approach apparently there is an attribute-based way to override default mappings at your classes which autogenerate everything else to specify differentiations at the database such as a different name for a column I suppose. Since version 4.3 of Entity Framework there has been migration support to account for the data loss that might come with dropping and recreating a database in the Code-First approach and the book warns of a terrible learning curve which seem consistent with what I have experienced myself.

Use T-SQL to get a list of users and roles for all databases at a server!

DECLARE @UsersAndRoles TABLE
(
   db varchar(50),
   access varchar(4),
   name varchar(255)
)
declare @db varchar(50)
declare @sql varchar(255)
DECLARE curs CURSOR FOR SELECT name FROM master.sys.databases WHERE name NOT IN ('master','tempdb','model','msdb') order by name
OPEN curs
FETCH NEXT FROM curs into @db
WHILE @@FETCH_STATUS = 0
   BEGIN
      BEGIN TRY
         select @sql = 'USE ' + @db + '; SELECT db=''' + @db + ''', access=''user'', name
               FROM sysusers WHERE (islogin = 1 AND isntname = 1) OR issqluser = 1
               ORDER BY name'
         INSERT INTO @UsersAndRoles EXEC sp_sqlexec @sql
         select @sql = 'USE ' + @db + '; SELECT db=''' + @db + ''', access=''role'', name
               FROM sysusers WHERE issqlrole = 1 ORDER BY name'
         INSERT INTO @UsersAndRoles EXEC sp_sqlexec @sql
      END TRY
      BEGIN CATCH
         INSERT INTO @UsersAndRoles(db,access,name) VALUES (@db, 'FAIL', 'no
               access to inspect')
      END CATCH
      FETCH NEXT FROM curs into @db
   END
CLOSE curs
DEALLOCATE curs
SELECT * FROM @UsersAndRoles ORDER BY db

 
 

This is the only way to use a magic string with a USE statement. You have to put SQL in a magic string and then call sp_sqlexec unfortunately.

The $_ variable in Perl is kinda like the clipboard in that it is a cache of the most recently used variable.

I guess that's not much like the clipboard at all really. The clipboard has a cache of that which is copied or cut most recently so that you may paste from the clipboard. No one wants to think about this stuff (Perl) anymore. You may spit something out as HTML in PHP with an echo like so:

echo "<h1>ghetto</h1>";

 
 

Variable names in PHP are led by dollar signs.

Hits Counters

Do you remember the old counters for a number of visitors from the 1990s web sites? You never see those anymore. No one has a hit counter.

Sunday, September 16, 2018

Matt's Bar

Located at 3500 Cedar Avenue South, in Minneapolis, Minnesota 55407, Matt's Bar sits at the Southeast corner of East 35th Street and Cedar Avenue South. I visited it for the first time today.

If is one of two locations that claims to have invented the Jucy Lucy, a dish original to Minneapolis, which is basically a Cheeseburger wherein there is a pocket of queso inside of the hamburger patty itself in a thin horizontal bubble.

The 5-8 Club at 5800 Cedar Avenue South (yes, the same street) in Minneapolis, Minnesota 55417 is the rival to Matt's Bar. I tried the 5-8 Club today too. There the Juicy Lucy is spelled Juicy Lucy and not Jucy Lucy I noted.

So who has the better Lucy? Alright, without being able to weigh in on who was first, Matt's is better. The queso was boiling hot and popped out (pressurized) all over me when I bit into it. The waitress even told me to be careful. The surprise entertained me. The 5-8 Club in contrast gave me a Lucy with a comparably underwhelming effect. There was even cheese on top of the patty to offset how the Juicy part was weak.

The 5-8 Club has a less interested building. I took photos of it too, but it is not photogenic like Matt's Bar so I'll only give the photos of Matt's Bar here. Negatives about Matt's bar include having to use an ATM (automated teller machine) inside the place because they would only take cash or check for payments, having to wait forever to be seated, having to wait forever for food, and having to go downstairs to a basement to use a restroom.

The number on a credit card reveals if it is debit or credit.

I don't work at Paymetric anymore and I don't know how this works. I just noticed that amazon.com knew what kind of MasterCard I had based on the number.

Work From Home?

I'm not a fan. I never once tested the RSA token while I was at Wells Fargo Advisors. However, here in Minnesota, my immediate superior asked that I make sure I could at least log in this weekend and so I went through that exercise, with success, yesterday.

The process is not what I expected. I had to buy at CAT5 cable at Best Buy and then hardwire my work laptop to my router at home for the first time where I would log in giving an eight digit pin when I was prompted for a "password" instead. Strange, strange, strange. After the pin is set one logs in giving the pin chased by the six numbers on the RSA token which change every one minute as a "password" and at this point one may just use the wireless and one doesn't have to have a LAN connection. (LAN being used very loosely.) When one powers up the laptop, instead of logging in normally one clicks an icon at the lower right in Windows 10 which looks like two computer monitors overlapping for the VPN entry.

Friday, September 14, 2018

Breaking things up onto separate threads in modern C# makes for some asynchronous messaging.

Consider this static utility, tucking away some things to static state so that they may be later used in an action.

using System;
using System.Collections.Generic;
using MyOwnStuff.Core.Objects;
namespace MyOwnStuff.Core.Utilities
{
   public static class ChunkText
   {
      private static InitialDetails _initialDetails;
      private static ExternalDependencies _externalDependencies;
      private static Action<Alert> _alertAction;
      private static Action<string> _updateFileSize;
      
      public static Alert TextOnly(InitialDetails initialDetails, ExternalDependencies
            externalDependencies, Action<Alert> alertAction, Action<string> updateFileSize)
      {
         _initialDetails = initialDetails;
         _externalDependencies = externalDependencies;
         _alertAction = alertAction;
         _updateFileSize = updateFileSize;
         Action<List<string>> writeAction = WriteLines;

         externalDependencies.FileReading.ReadLineByLine(initialDetails, writeAction);
         return new Alert(String.Format("Count slowly in your head to... sixty? Attempting
               parsing: {0}", initialDetails.FromPath), false);
      }
      
      private static void WriteLines(List<string> lines)
      {
         _updateFileSize(String.Format("{0} lines", lines.Count));
         _alertAction(new Alert(String.Format("Done parsing: {0}", _initialDetails.FromPath),
               false));
         _externalDependencies.FileWriting.WriteChunksFromLines(lines, _initialDetails,
               _alertAction);
      }
   }
}

 
 

Alright the IFileReading looks like so. Do note, no hint of async here.

using System;
using System.Collections.Generic;
using MyOwnStuff.Core.Objects;
namespace MyOwnStuff.Core.Interfaces
{
   public interface IFileReading
   {
      void ReadLineByLine(InitialDetails initialDetails, Action<List<string>> pseudoReturn);
      Byte[] SimpleRead(InitialDetails initialDetails);
   }
}

 
 

FileReading implements IFileReading and now we do have an async method even though that is not at the interface. This method needs to be void instead of returning a task as I learned the hard way that returning a task screws up the await implemenation partway down the method and sabotages the action that chases it.

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using MyOwnStuff.Core.Interfaces;
using MyOwnStuff.Core.Objects;
namespace MyOwnStuff.Infrastructure.ExternalDependencies
{
   public class FileReading : IFileReading
   {
      public Byte[] SimpleRead(InitialDetails initialDetails)
      {
         return File.ReadAllBytes(initialDetails.FromPath);
      }
      
      public async void ReadLineByLine(InitialDetails initialDetails, Action<List<string>>
            pseudoReturn)
      {
         List<string> list = new List<string>() {};
         await Task.Run(() => { ReadLineByLine(list, initialDetails.FromPath); });
         pseudoReturn(list);
      }
      
      private void ReadLineByLine(List<string> list, string fromPath)
      {
         using (var streamReader = new StreamReader(fromPath))
         {
            while (streamReader.Peek() != -1)
            {
               string line = streamReader.ReadLine();
               list.Add(line);
            }
         }
      }
   }
}

 
 

We want the extra work of using async/await here to break file writing of chunks of the bigger file that would happen downstream of the read to happen on a different thread, right? Also some of the actions that we use to work around the fact that we cannot return anything may implement methods in the UI that set copy at labels to give us some reporting on what is happening in a long process. Note the use of...

streamReader.Peek() != -1

 
 

...which is pretty cool!

Microsoft Office Professional Plus 2010 cannot verify the license for the product. You should repair the Office program by using Control Panel.

Groan! Just restart your laptop when you see this error.

Thursday, September 13, 2018

How to read from a flat file n number of lines in in C# and how to add all of an IEnumerable to a List in C#.

IEnumerable lines = File.ReadLines(fromPath).Skip(counter).Take(1000);
list.AddRange(lines);

TSM is the IBM Tivoli Storage Manager.

This is a tool for long-term archival management, the sort of offsite backup stuff that has replaced the tape backups of yore.

Documentum is for enterprise-level documentation.

word

parch or Partch

What is the sixth word of this song? Is it parch or Partch? It depends on where Google takes you.

What would it mean to Partch someone like Harry Partch the composer? Rick Santorum's last name, Santorum, has become the subject of the best black hat SEO ever making the meaning of the word pretty nasty. Was this a similar swipe at Harry Partch or just a lasting typo? If you are looking at this ten years in the future and the link and the video are gone, the video was The Great Commandment by Camouflage (a band that ripped of Depeche Mode) and Santorum is everything that leaks back out of the ass after anal sex.

Any changes you manually make in a .Designer.cs file in a WinForms app are likely to get messed up when you drag something from the Toolbox of Visual Studio 2017 into the WinForm.

If you change text names of controls to your own goofy thing for example, these will get renamed back to something consistent with the C# names of the controls. I guess such a renaming should go in the .cs code for the WinForm and stamp over the .Designer.cs setting by just happening downstream in code.

Make an artificially fat flat file in C# for your own testing from a slimmer file.

using System;
using System.IO;
using System.Threading.Tasks;
using MyOwnStuff.Core.Interfaces;
using MyOwnStuff.Core.Objects;
namespace MyOwnStuff.Infrastructure.ExternalDependencies
{
   public class FileWriting : IFileWriting
   {
      public async void FattenFile(byte[] bytes, string fileName, InitialDetails initialDetails,
            Action<Alert> alertAction)
      {
         int counter = 0;
         string filePath = String.Format("{0}\\{1}", initialDetails.ToPath, fileName);
         while (counter < initialDetails.TimesToDuplicateInFattening)
         {
            if (counter == 0)
            {
               await Task.Run(() => { FlattenFile(bytes, filePath, initialDetails,
                     FileMode.Create); });
            }
            else
            {
               await Task.Run(() => { FlattenFile(bytes, filePath, initialDetails,
                     FileMode.Append); });
            }
            counter++;
            if (counter == initialDetails.TimesToDuplicateInFattening)
            {
               alertAction(new Alert(String.Format("The file has been successfully written to:
                     {0}\\{1}", initialDetails.ToPath, fileName), false));
            }
            else
            {
               alertAction(new Alert(String.Format("Writing pass {0} of {1} to {2}\\{3}.", counter,
                     initialDetails.TimesToDuplicateInFattening, initialDetails.ToPath, fileName),
                     false));
            }
         }
      }
      
      private void FlattenFile(byte[] bytes, string filePath, InitialDetails initialDetails,
            FileMode fileMode)
      {
         using (Stream stream = new FileStream(filePath, fileMode))
         {
            stream.Write(bytes, 0, bytes.Length);
         }
      }
   }

}

 
 

Awesome! Things to note include that the public method signature may be async but the matching method in the interface will not use the async keyword, the last of the actions called seems to clobber the message I just get back from the method calling the public method above wherein both messages get put to a label in a WinFroms app, and that, finally, I read online that you have to asynchronously make labels in a WinForms app listen like so, but this is really no longer the case with async/await:

this.foo.BeginInvoke(new Action(() => { this.foo.Text = "bar"; }));

Make a vapid Action on the fly for a unit test in C#.

Action<Alert> alertAction = new Action<Alert>((Alert alert) => { });

a passthrough is a logic gate that enables a signal to "pass through" unaltered

This definition comes from the all-knowing Wikipedia! It suggests there may be "daisy chain logic" with passthroughs.

Get the number of digits in a positive integer in C#!

double numberOfDigits = Math.Floor(Math.Log10(myNumber) + 1);
int betterNumberOfDigits = Convert.ToInt32(numberOfDigits);

 
 

This might be bogus honestly. I don't think I got this working yesterday.

Read through a flat file one line at a time in C#.

string line;
using (var streamReader = new StreamReader(initialDetails.FromPath))
{
   while ((line = streamReader.ReadLine()) != null)
   {

 
 

I bit into this yesterday in the name of chunking a large file out to smaller ones. I learned the hard way that you should pull all of the lines out to a list of strings and THEN afterward attempt the writing. Do not try to write to other files while reading/looping. The while loop misbehaves.

Index (zero based) must be greater than or equal to zero and less than the size of the argument list.

Can you see how this causes that error?

var yikes = String.Format("fail{0}");

 
 

A fix:

var yikes = String.Format("fail{0}"," no more");

Wednesday, September 12, 2018

How do I loop in Entity Framework in a .NET Core project?

Well page 156 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis suggests you may run these five NuGet console commands:

  • Install-Package Microsoft.EntityFrameworkCore -Version 2.0.1
  • Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 2.0.1
  • Install-Package Microsoft.EntityFrameworkCore.SqlServer.Design -Version 2.0.0-preview1-final
  • Install-Package Microsoft.EntityFrameworkCore.Tools -Version 2.0.1
  • Install-Package Microsoft.EntityFrameworkCore.Tools.DotNet -Version 2.0.0

res ipsa loquitur

Managed Debugging Assistant 'ContextSwitchDeadlock' : 'The CLR has been unable to transition from COM context 0xcd251c80 to COM context 0xcd251b58 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.'

swapping out what driver a PDF is associated with in IIS

I remember doing (managing) a project for Cenetron Diagnostics while at Headspring in which we had to conditionally show users PDFs if they were logged in but we didn't want users to be able to just send links to the PDFs to just anyone. A Ukrainian offshore team was working on this if I remember correctly. Their solution was to by default associate the .pdf extension with the wrong driver so that IIS couldn't really serve a PDF when one browsed to one. Then, if one was logged in and one was looking at the right stuff (I can't recall how one man's PDF was differentiated from all the others. Maybe we just gave them random GUIDs for names in hopes they'd be unguessable.) IIS would reassociate the applicable driver to the PDF. Kinda cool and kinda ghetto.

How is SonarQube better/different than HP Fortify?

SonarQube will increase its scrutiny of your code as it crawls your code. Your code will progressively, in theory, grow better over time. One of the things that is going to be demanded of you is that you unit test your code. SonarQube is really only for .NET and Java codebases while HP Fortify will crawl things like T-SQL too.

 
 

@bellingard points out over Twitter that SonarQube does support SQL and a bunch of other languages.

Axway is a tool for transferring files securely with some sort of standards between two corporate entities.

ECG stands for "preprocessed GOC source code file error checking version" believe it or not and GOC for "GEOS Objective C" and GEOS for Geoworks "Ensemble Operating System" I think. You set up an ECG server with Axway to either be a receiver or to be, well, pushy.

RTM stands for Ready to Manufacture

It is a "shrink-wrapped" packaging of a deliverable and it dates back namewise to when CD-ROMs or some other physical deliverable were shrink-wrapped. Anymore, in a softer era, this deliverable would be a versioned release of a .dll or some similar package.

Tuesday, September 11, 2018

Azure Table Storage

This is the Azure way to do NoSQL! You can keep NoSQL gunk in the cloud. It is namedropped on page 155 of "ASP.NET Core 2 and Angular 5" by Valerio De Sanctis, so I had to look it up at Google.

How do I fish out the value of a selected radio button in a WinForms app?

This really sucks, but you have to do it like so:

string radioButtonSetting;
if (Foo.Checked) radioButtonSetting = Foo.Text;
if (Bar.Checked) radioButtonSetting = Bar.Text;
if (Baz.Checked) radioButtonSetting = Baz.Text;
if (Qux.Checked) radioButtonSetting = Qux.Text;

 
 

I hope this is my last posting for a while on WinForms. Ha!

Make a WinForms label grow text right to left instead of left to right.

This was surprisingly painful to figure out. My solution looks like this:

this.toPath.AutoSize = false;
this.toPath.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.toPath.Location = new System.Drawing.Point(-1050, 308);
this.toPath.Name = "toPath";
this.toPath.Size = new System.Drawing.Size(1794, 23);
this.toPath.TabIndex = 10;
this.toPath.Text = "?";
this.toPath.TextAlign = System.Drawing.ContentAlignment.MiddleRight;

 
 

AutoSize must be false, TextAlight should be MiddleRight, and the Anchor set to Right. Beyond all that, you must drag out a long-sized box for the whole of the label as a box snugged up against minimalistic starting text, such as my question mark, will not grow outwards in the right direction.

Disable and reenable a button in WinForms!

this.submit.Enabled = false;
DoWhatYouWill();
this.submit.Enabled = true;

How may I make a list of radio buttons not have a default value in WinForms?

This is tricky. You may achieve the effect initially by just setting the TabIndex of all of the radio buttons to be the same thing, but once a button is pressed the first of the radio buttons will get selected. You may make an "invisible" RadioButton that you hide out of sight and use that as the first radio button, but that too has its challenges as a user may tab back to the radio buttons and change back to the bogus setting with the arrow keys. Also you have to compensate for the bogus setting in your code of course.

Set the color of a label in a WinForms app.

if (alert.IsError)
{
   this.message.ForeColor = Color.Red;
}
else
{
   this.message.ForeColor = Color.Green;
}

 
 

By the way, there is also a BackColor setting for the labels too. Cool stuff.

Ted Neward

The one time I saw Ted Neward speak it was the one time I went to No Fluff Just Stuff in 2011 and his talk got canceled and thus there was a makeup talk at the very end of the conference after all of the other talks were done in which just a few of us were in attendance. I can't really remember it. It had something to do with mobile applications. The thing I remember the most is him venting about Apple and saying that the whole iPhone platform is really just about what Steve wants and what Steve thinks. This was before Steve Jobs died later in the year. Ted was right. There was no community input into the iPhone. It was just one man's vision. I also remember from this talk Ted suggesting to another in the crowd that he spend ten hours a week trying to grow professionally. "Just cut out your TV time." is how he put it.

Monday, September 10, 2018

A .pst file is where Microsoft Outlook may save your data on a server.

Several GBs of info can build up over a few years’ time.

a process for updating SSL certificates at a server with Venafi

Alright, there are basically two ways to approach this challenge. There is an API to call to request a new certificate. In this scenario one typically creates a new user for the server and the user has to become a part of the Venafi group. (There is a read group and a write group, and I'd imagine the write group is more applicable.) In the API approach you have to have something at the server, perhaps a Windows Service, watching for a certificate to expire and then hitting the API when applicable. The other approach is "built-in provisioning" and in this circumstance one configures Venafi to access the server through an account for the server which has administrative permissions and then pushes down the certificate when the time is right. You may map where a certificate goes, etc. There is a distinction between a production policy and a non-production policy in that the production policy has the extra workflow steps of taking the server down before the write of the new certificate and then bringing it back up again. This safeguard keeps the server from being accessed without its certificate intact.

Set up the display for multiple monitors in Windows 10.

  • Right-click in the desktop and then pick: "Display settings"
  • Assuming the "Display" tab is selected at the left, scroll down to: "Multiple displays"
  • Click the "Detect" button.

 
 

Addendum 11/27/2018: At the "Multiple displays" dropdown list you may need to pick "Extend these displays" to get this stuff to work.

Only the right Alt key allows for a vertical selection in Visual Studio 2017???

I have not been able to get this trick to work in Visual Studio for some time. I Googled against it today and found that I only need to hold the Alt key anymore, but I still couldn't get it to work. Then, to my surprise, it worked if I held the right Alt key. I don't know what I've installed to make this setting so wacky. ReSharper maybe? Yikes. Nevermind, I figured out what I was doing wrong. You have to press and hold Alt first before you first click the mouse down to drag. Both Alt keys work for me now.

There is a baseline SQL standalone language that no one ever uses by itself.

Structured Query Language (or SQL) is its own thing independent of T-SQL and PL/SQL for Oracle (the PL is for Procedural Language) which sort of extend it to make their own flavors. Naturally, no one uses SQL standalone, so it was easy for me to think T-SQL and PL/SQL were just two similar ways of doing the "same" thing. I had an interview at Gimmal in this latest round of job hunting in which I was asked an interview question about the types of joins in SQL and I started speaking to the types of joins in T-SQL and the guy doing the interview straightened me out.

Saturday, September 8, 2018

Spoonbridge And Cherry

Husband and wife, Claes Oldenburg and Coosje van Bruggen made this tacky piece of art in the 1980s and it is the most famous work of art in the Twin Cities. It sits at the Minneapolis Sculpture Garden and I took a photo of it today.

I saw Alex Winter speak on using GraphQL with Angular at AngularMN on Wednesday night.

GraphQL is a trending approach to data hydration and interactions. Just as SQL stands for Structured Query Language the QL in GraphQL would be for Query Language. GraphQL in tandem with React, as it largely rears its head currently (Tamara Temple had an example at JavaScript MN in adjacent Minneapolis a week earlier), is used heavily at Facebook, but an Angular implementation is certainly not far-fetched. Alex started out by spinning up an Express server for such an orchestration which looked like so and tied into MongoDB with Mongoose.

import express from 'express';
import bodyParser from 'body-parser';
import { graphqlExpress, ApolloServer } from 'apollo-server-express';
import { gql } from 'apollo-server-express';
import axios from 'axios';
 
const TYPEDEFS = gql`
   type Query {
      test_query: Test
   }
   type Test {
      test_field_1: String
      test_field_2: Int
      test_field_3: Boolean
   }
`;
 
const SERVER = new ApolloServer({
   typeDefs: TYPEDEFS,
   resolvers: RESOLVERS,
   playground: {
      endpoint: 'http://localhost:4000/graphql',
      settings: {
         'editor.theme': 'dark'
      }
   }
});
 
const app = express();
 
app.use(cors());
 
mongoose.connect('mongodb://localhost/graphqlserver');
const connection = mongoose.connection;
 
connection.once('open', () => {
   console.log('MongoDB connection has been established successfully');
});
 
SERVER.applyMiddleware({
   app: app
});
 
app.listen(4000, () => {
   console.log('Express server running on port 4000');
});

 
 

We need ApolloServer to crosstalk with GraphSQL, a domain-specific language, and do take note of the playground. The playground may be brought up in a browser and you may thumb through what is in GraphQL that way not unlike using SSMS with T-SQL. Robo 3T is a more formal tool for the same job as the playground, but a neat thing about the playground is that you may share the URL with a client (if you're a consultant) and let them easily play with it and it is elementary. There will be a little "Schema" tab to expand at the far right to see the meat of what's what in JSON form. server.js is given above and here is schema.js which shows off our basic types which will hydrate from Mongo. The app has a superheroes theme based on the Tour of Heroes example that is all too overused.

import { gql } from 'apollo-server-express';
 
const TYPEDEFS = gql`
   type Hero {
      id: String
      name: String
      voteCount: Int
   }
   type Query {
      allHeroes(searchTerm: String): [Hero]
      hero(id: String!): Hero
   }
   type Mutation {
      addHero(name: String!): Hero
      upvote(id: String!): Hero
      downvote(id: String!): Hero
   }
`;
 
export default TYPEDEFS;

 
 

Alright, herein the exclamation mark in the case of String! Implies that the String is required and [Hero] implies an array of Hero objects. This is some of the DSL syntax for GraphQL. Alright, why do this at all? Why do I care? There are a few benefits. With GraphQL, if one were grabbing, say people from a "rolodex" (database) one could just get the properties on the people one cared about instead of doing sort of a SELECT * and getting everything as a property on a JSON-object over the wire. This makes for snappier performance and it is not something you can easily do with REST endpoints. Another man in the crowd Wednesday night spoke to how we, as geek society, embraced REST over SOAP in an attempt to escape all of the heavy XML but ended up missing some of what was good about SOAP, such as type definitions which are really sparse in REST. This individual thought that GraphQL was the happy medium and that would be another point in its favor. I thought of this talk wherein I was told that IQueryable is really bad as it allows for queries to bleed out of the data layer of an app up to the UI and puts us back in the dirty old days of just having SQL inline in a spaghetti mess more or less. However, there are a few reasons to consider GraphQL more elegant than the IQueryable antipattern against the .edmx Entity Framework model as, first of all, GraphQL doesn't have to wrap one database like an .edmx. Instead sources from diversified servers can be queried to make an object in aggregate (different fields from different data sources) in a microservices pattern! Try that with REST or SOAP. Ha! It won't be lightweight. There are analytics tools for the searches one runs to see what one is searching against. There is also the concept of stitching in which you may fetch someone else's GraphQL syntax that is exposed and slurp it into your own. GraphQL for VSCode is a plugin that will color-code the GraphQL syntax in Visual Studio Code. There are other plugins for other IDEs obviously and GraphQL isn't the only one for Visual Studio Code. VSCode GraphQL is another. Graphcool allows for filtering and pagination with GraphQL. You may use GraphQL against what's in your local store in a Redux pattern as well. Alright, I tried to take photos of all of the files Alex showed off and the next one was resolvers.js, speaking of Redux, and I really only was able to capture a piece of the file on my end. It looks like this:

      if (searchTerm !== '') {
         return heroModel
            .find({ $text: { $search: searchTerm } })
            .sort({ voteCount: 'desc' });
      } else {
         return heroModel.find().sort({ voteCount: 'desc' });
      }
   },
   hero: (root, { id }) => {
      return heroModel.findOne({ id: id });
   }
},
Mutation: {
   upVote: (root, { id }) => {

 
 

Alex had the code above up while he was importing code to get GraphQL working with Angular. For example if you want ids to get created for the objects you may loop in "schema defaults" like so:

import uuid from 'uuid';

 
 

Obviously there is an implementation beyond the namespace. Also, Alex did an npm install of apollo-angular, apollo-angular-li, nk-http, apollo-client, apollo-cache-inmemory, graphql-tag, and graphql. Of these, apollo-angular-li, nk-http, apollo-client, apollo-cache-inmemory, graphql-tag, and graphql may just be procured by installing apollo-boost really. Alex's app.module.ts looked like so:

import { BrowseModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
 
import { AppComponent } from './app.component';
import { Apollo } from 'apollo-angular';
 
@NgModule({
   declarations: [
      AppComponent
   ],
   import: [
      BrowseModule
   ],
   providers: [],
   bootstrap: [AppComponent]
})
export class AppModule {
   constructor(private apollo: Apollo, private httpLink: HttpLink) {
   apollo.create({
         link: httpLink.create({ url: 'http://localhost:4000/graphql' }),
         cache: new InMemoryCache()
      });
   }
}

 
 

I was only able to capture of piece of tsconfig.json. It looks like so:

      "outDir": "./dist/out-tsc",
      "sourceMap": true,
      "declaration": false,
      "module": "es2015",
      "moduleResolution": "node",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "target": "es5",
      "typeRoots": [
         "node_modules/@types"
      ],
      "lib": [
         "es2017",
         "dom",
         "esnext"
      ]
   }
}

 
 

The esnext has to get added here for GraphQL to work and the TypeScript version has to be updated to 2.83. Here is app.component.html, a template for a component that Alex advertised.

<mat-list>
   <mat-list-item *ngFor="let hero or heroes | async">
      <h3 matLine>
         <b>{{hero.name}}</b>
      </h3>
      <p matLine>
         <button mat-raised-button color="primary"
               (click)="upvote(hero.id)">Upvote</button>
         <button mat-raised-button color="warn"
               (click)="upvote(hero.id)">Downvote</button>
         Vote Count:
         <span> {{hero.voteCount}} </span>
      </p>
   </mat-list-item>
</mat-list>

 
 

The component itself, app.component.ts, looks like this:

   stylesheets: ['.app.component.css']
})
export class AppComponent implements OnInit {
   title = 'frontend';
   searchTerm = '';
   heroes: Observable<Hero[]>;
 
   constructor(private heroService: HeroService) {}
 
   ngOnInit() {
      this.heroes = this.heroService.getAllHeroes(this.searchTerm);
   }
 
   onKeyUp() {
      this.heroes = this.heroService.getAllHeroes(this.searchTerm);
   }
 
   upvote(id: string) {
      this.heroService.upvoteHero(id).subscribe(
         data => {
            console.log('Upvoted', data);
         },
         error => {
            console.log('Failed to upvote the hero', error);
         }
      );
   }
 
   downvote(id: string) {
      this.heroService.downvoteHero(id).subscribe(
         data => {
            console.log('Downvoted', data);

 
 

The service it talks to, hero.service.ts, looks like so:

import { Injectable } from '@angular/core';
import { Apollo } from 'apollo-angular';
import { Query, Hero } from './hero.model";
import gql from 'graphql-tag';
import { map, filter } from 'rxjs/operators';
 
@Injectable({
   providedIn: 'root'
})
export class HeroService {
   constructor(private apollo: Apollo) {}
 
   getAllHeroes(searchTerm: string) {
      return this.apollo
         .watchQuery<Query>({
            pollInterval: 500,
            query: gql`
               query allHeroes($searchTerm: String) {
                  allHeroes(searchTerm: $searchTerm) {
                     id
                     name
                     voteCount
                  }
               }
            `,
            variables: {
               searchTerm: searchTerm
            }
         })
         .valueChanges.pipe(map(result => result.data.allHeroes));
      }
 
      upvoteHero(id: string) {
         return this.apollo.mutate({
            mutation: gql`
               mutation upvote($id: String!) {
                  upvote(id: $id) {
                     id
                     name
                     voteCount
                  }
               }
            `,
            variables: {
               id: id
            }
         });
      }
 
      downvoteHero(id: string) {
         return this.apollo.mutate({

 
 

A hero model in the Angular code, hero.model.ts, looks like this:

      query: gql`
         query allHeroes($searchTerm: string) {
            allHeroes(searchTerm: $searchTerm) {
               id
               name
               voteCount
            }
         }
      `,
      variables: {
         searchTerm: searchTerm
      }
   })
   .valueChanges.pipe(map(result => result.data.allHeroes));
}
 
upvoteHero(id: string) {
   return this.apollo.mutate({
      mutation: gql`
         mutation upvote($id: String!) {
            upvote(id: $id) {
               id
               name
               voteCount
            }
         }
      `,
      variables: {
         id: id
      }
   });
}
 
downvoteHero(id: string) {
   return this.apollo.mutate({

 
 

Regrettably, I only have partial representations of the last four files, but you get the idea, right? This was my first time to attend AngularMN. It was at Virtuwell's office in St. Paul, Minnesota. Thanks to them and a Michael Jordon, pictured with Alex Winter here, for hosting.

Friday, September 7, 2018

Azure Service Fabric

It's the Azure way to build microservices.

Browse for a file in a WinForms application.

Drag OpenFileDialog and FolderBrowserDialog out of the Dialogs section in the Toolbox in Visual Studio 2017. Use the OpenFileDialog to find a file like so:

private void inButton_Click(object sender, EventArgs e)
{
   DialogResult result = openFileDialog.ShowDialog();
   if (result == DialogResult.OK)
   {
      string whereAmI = openFileDialog.FileName;
      Console.WriteLine(whereAmI);
   }
}

 
 

Use a FolderBrowserDialog to find a folder like so:

private void outButton_Click(object sender, EventArgs e)
{
   DialogResult result = folderBrowserDialog.ShowDialog();
   if (result == DialogResult.OK)
   {
      string whereAmI = folderBrowserDialog.SelectedPath;
      Console.WriteLine(whereAmI);
   }
}

 
 

Addendum 9/13/2018: The folder path with NOT have a trailing backslash on it.