C# Interactive Shell – Where have you been all my life?

Holy crap. I wish I knew about this before. I used to use LinqPad for these simple tests.

Suppose you want to verify what a certain format of DateTime is. Before LinqPad I would occasionally spin up a new console project to verify.

Turns out Visual Studio has a shortcut for this. It is CTRL + E + E

Enter expression, hit enter, see result. ūüôā

It also works by highlighting a block of code and hitting the key combo. It will auto execute and show you the results.

The shell¬†can even use classes from your project!¬†Just right click on your solution and select “Reset Interactive from Project”.

Filip Ekberg has a more detailed description:¬†Using the C# Interactive Window that comes with Roslyn ‚Äď Part 2

Web Development Tutoring – 1 Month Update

Considering how much time I spend online, you would think I would have considered this option. But no, I heard about online tutoring and Wyzant on an episode of Side Hustle School.

I learned quite a bit in my first month from teaching others. Of course I could just look this up and use it, but having to also explain it to someone forces a certain internalization of the concepts.

  • JS/jQuery – I have used these before, but now I can truly now say I “know” them ūüėČ
    • $.getJSON
    • $.each
    • JSON Objects
  • I was less familiar with these, but tutoring forced me to¬†learn more and actually use it.
    • Canvas & SVG
    • Angular
    • TypeScript and ES6
  • Others
    • Integrating MVC with Gmail
    • Regular Expressions – Though I can use it, explaining some of the concepts to someone else was interesting. Thank you http://regex101.com

Debugger – Pause On Exception

This one just requires its own section. Somehow, I never really used this option in the Browser Developer Tools. Perhaps its because I usually just use JavaScript with jQuery to move around DOM elements; these projects forced me to manipulate data objects and arrays¬†in JS. The trouble with using real data is that sooner or later you will encounter something that does not meet your assumptions.¬†If the data is in a loop, one alternative is to simply step through the loop. A better one is to turn on “Pause on Exception”, this way your loop will stop on the exact object that cause the error and you can check your assumptions.

First month statistics (2/20/2017 – 3/23/2017)

  • 9 Students & 28 Sessions
  • 46 hours of tutoring, averaging about 100 minutes each
  • Majority of the sessions are over JavaScript and HTML

But… What about the money?

If it wasn’t about the money I’d probably just use this time to play League of Legends and browse Reddit. (Warning: Don’t click either link until you are done with the semester)

I wasn’t sure where to set the price at first but I figured I needed my first students and reviews so I started out at $19/hr. Initially Wyzant takes a 40% commission, so the take home rate is $11.40.

My first month average is actually closer to $16.25 because I have adjusted my prices several times.

Considering that I am considered a 1099 contractor, this is certainly not a fair hourly wage for my skill level. I will find a working good working rate, but in the meantime I get to do what I enjoy!

Shopify Theme: Hide Dropdown if Only One Variant Exists

I was working with a friend on his Shopify store and think others may find our results useful.

Problem:

Recently take5drink.com started offering just one product size: the 12-pack. Their Shopify theme was displaying the size drop-down regardless, so we needed a way to hide it when only one option is available.

Shopify Hide Variants Before and After

Solution:

We¬†don’t want to physically remove the drop-down from the screen because it is used by the “Add to Cart” button. We simply want to hide it from the user. We can do that with a simple CSS class.

  hidden {
    display:none;
  }

Locate the variant drop-down, in our case it was located in index.liquid, but yours may be on product.liquid. Searching the template for “product.variants” is a good place to start. It will look something like this:

<label>Select Size:</label>
<select id="product-select" name="id">
  {% for variant in product.variants %}
    <option{% if variant == product.selected_or_first_available_variant %} selected{% endif %} data-sku="{{ variant.sku }}" value="{{ variant.id }}">
{{ variant.title }} - {{ variant.price | money }}
    </option>
  {% endfor %}
</select>

We want to hide the label and the select box when there is only one product variant. The solution is to wrap the code in a div, with a conditional hidden class.

<div class="{% if product.variants.size == 1 %}hidden{% endif %}">
  <label>Select Size:</label>
  <select id="product-select" name="id">
  {% for variant in product.variants %}
    <option{% if variant == product.selected_or_first_available_variant %} selected{% endif %} data-sku="{{ variant.sku }}" value="{{ variant.id }}">
      {{ variant.title }} - {{ variant.price | money }}
    </option>
  {% endfor %}
  </select>
</div>

What is going on?

  • Notice the bold text, our new div is now a container for both the label, and the select element. This way we can hide both in one operation.
  • The div element has a class attribute
  • We use the “if” control flow tag to¬†check if the size of the product.variants collection is equal to 1. If it is, we add “hidden” to the div class. Otherwise, the div class is left blank.

Closing Note:

If¬†Shopify theme customization is stressing you out, you should Take 5 and check out my friend’s shop:¬†take5drink.com

 

Integrating TinyMCE with SharePoint 2010

We use SharePoint as a CMS for some of our sites. In general the rich text editor (RTE) works pretty well, but the HTML output is ugly. Also we wanted a way to add custom formatting styles.

I read a few articles on customizing the RTE but it all just seamed too clunky and I really wanted something that would look good in SharePoint and in our MVC app. Check out this article if you are interested in customizing the MS RTE.

I’ve used Tiny MCE before with CRM 4.0 so I figured I would try it with SP2010. Its licensed under LGPL so it’s pretty non-invasive in the corporate world.

Overview

  1. Add a multi-line column with enhanced rich text. (You probably already have this)
  2. Create a TinyMCE configuration file in a document library
  3. Modify NewForm.aspx and EditForm.aspx to use TinyMCE.

Add a Multi-Line Column With Enhanced Rich Text

You probably already have rich text editor in SharePoint, but here is a reminder.

  1. List Settings
  2. Add Column
    • Multi-line text
    • Enhanced Rich Text

Create a TinyMCE Configuration File in a Document Library

You want to store your configuration in a document library so that it can be used in more than one location. We need to link to it in at least 2 pages, but you may want to use one config file on multiple lists and sites.

Also, it is convenient to¬†open the document library with Windows Explorer and then open the file in Notepad++. This way you can edit/save it directly from the editor without having to upload. The file extension¬†doesn’t really matter, I used txt.

Here is the output from my configuration file.

<script src="//cdn.tinymce.com/4/tinymce.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">

$(document).ready(function(){

  //Use an $.each method to replace all RTEs
  $('div.ms-rtestate-write')
    .each(function(index, element){
 
      //Get rid of border and padding b/c its ugly
      $(element).parent().css('padding', '0px');
      $(element).parent().css('border', 'none');
 
      //Replace the RTE with TinyMCE
      var id = $(element).attr('id');
      tinymce.init({
        selector: '#' + id,
        setup: function(editor) {
          editor.on('change', function(e) {
            $('#' + id).html(editor.getContent());
          });
        }
      });
    });
  });
</script>

I excluded most of my TinyMCE configuration because you can find all of that on the API reference. I want to show the bare minimum to get this to work in SharePoint 2010.

I am loading TinyMCE and jQuery from CDN for simplicity but you can store it on you server if you like.

SharePoint 2010 is not using a hidden textarea like SharePoint 2007. It is actually embedding the content¬†in the HTML DOM.¬†That means we have to read the the editor content and and replace the DOM node. This onChange event does that for us. If you don’t include it your changes will not be saved.

setup: function(editor) {
  editor.on('change', function(e) {
    $('#' + id).html(editor.getContent());
  });
}

Modify NewForm.aspx and EditForm.aspx to use TinyMCE

You can do this in SharePoint designer or the browser. I will describe the Browser method.

  1. Disable the dialog for this list. This will allow us to edit the dialog pages in the browser.
    • List Settings -> Advanced Settings
      • Launch forms in dialog? = No
  2. On both NewForm.aspx and EditForm.aspx do the following steps. (To access each page simply start a new list item or edit an existing one)
    • Site Actions -> Edit Page
    • Add a Web Part
    • Media and Content -> Content Editor -> Add
    • Do not edit the content editor body directly, instead
      • Click Edit Web Part in the right panel
      • Paste a link to the config file created in step 2 into the Content Link input box
  3. (Optional) Re-enable the dialog for the list. I prefer the non-dialog version when using TinyMCE

Known Issues

  • You can still see the built in RTE controls in the ribbon if you click on the TinyMCE editor just right. I couldn’t figure out how to disable that but decided we can just ignore it in our environment.

Next Steps

This is outside of scope for this article since I am only focusing on SP2010 integration but here are a few links you may find useful.

Configuring TinyMCE in SharePoint 2007 is slightly different. Here is an article by Josh McCarty that describes it pretty well. I used it as a starting point to get my version working in 2010.

Embedding DLLs in a Compiled Executable

The Problem

For fun I am building a building a multi-platform screen saver in C# that I want to execute as a UWP (Universal Windows Platform) app and as classic screen saver using WPF (Windows Presentation Foundation).

This requires the logic to be left in PCLs (Portable Class Libraries), which results in a bunch of DLLs in the output directory. To build a classic screensaver I need a single EXE. So I went looking for a way to embed all resources in a single EXE.

Stack Overflow to the Rescue

http://stackoverflow.com/questions/189549/embedding-dlls-in-a-compiled-executable

Ok, the fact that this exists and is so easy to use is simply blowing my mind.

  1. Install-Package Costura.Fody
  2. Install-CleanReferencesTarget

Build your project and check the app.publish folder in your output directory (\bin\Debug\app.publish)

For my screen saver project I simply need to rename the extension from exe to scr and I am done. Now to figure out the installer part. ūüôā

Screens Saver Gallery

The UWP¬†is already in the¬†Windows App Store. I must warn you,¬†its not like a classic screen saver that opens after inactivity, that’s not available for UWP (Universal Windows Platform) apps. Its¬†basically a full screen app that shows pretty pictures.

Its free, try it out. ūüôā

https://www.microsoft.com/en-us/store/apps/screen-saver-gallery/9nblggh5j8tx

Xml Polymorphism

In my scenario a policy XML holds a collection of Risk elements. The problem is that each Risk is actually a different type depending on the RiskCode. Each type has different properties, etc. I wanted to use attribute based deserialization without writing a custom parser so I decided to transform the risk element based on the RiskCode.

Here is my approach.

  1. Use Linq To Xml to transform the input document
    • Change the Risk element name based on RiskCode
  2. Use attribute based deserialization
    • All risk nodes map to a class that inherits Risk. Risk contains elements that are common to all classes.

I like this because I think the Linq to Xml transform is much simpler to understand compared to XSLT and the attribute based deserialization should be easier to maintain. We can standardize risk behavior by adding interfaces or virtual methods to the base class.

Input XML

<Policy>
  <PolicyNumber>123</PolicyNumber>
  <Risks>
    <Risk>
      <RiskCode>FOO</RiskCode>
      <Name>Blueberry</Name>
    </Risk>
    <Risk>
      <RiskCode>BAR</RiskCode>
      <Number>2</Number>
    </Risk>
  </Risks>
</Policy>

Transforms To

<Policy>
  <PolicyNumber>123</PolicyNumber>
  <Risks>
    <FooRisk>
      <RiskCode>FOO</RiskCode>
      <Name>Blueberry</Name>
    </FooRisk>
    <BarRisk>
      <RiskCode>BAR</RiskCode>
      <Number>2</Number>
    </BarRisk>
  </Risks>
</Policy>

Class Model

public class Policy
{
    [XmlElement("PolicyNumber")]
    public string PolicyNumber { get; set; }
 
    [XmlArray("Risks")]
    [XmlArrayItem("FooRisk", typeof(FooRisk))]
    [XmlArrayItem("BarRisk", typeof(BarRisk))]
    public Risk[] Risks { get; set; }
}
 
public abstract class Risk
{
    [XmlElement("RiskCode")]
    public string RiskCode { get; set; }
}
 
public class FooRisk : Risk
{
    [XmlElement("Name")]
    public string Name { get; set; }
}
 
public class BarRisk : Risk
{
    [XmlElement("Number")]
    public int Number { get; set; }
}

Transform

public static string TransformXml(string input){       
    var doc = XDocument.Parse(input);
 
    foreach (var risk in doc.Descendants("Risk"))
    {
        switch (risk.Element("RiskCode").Value)
        {
            case "FOO":
                risk.Name = "FooRisk";
                break;
            case "BAR":
                risk.Name = "BarRisk";
                break;
        }
    }
    return doc.ToString();
}

Usage Example

static void Main(string[] args)
{
    var transformed = TransformXml(xmlText);
    var policy = Deserialize<Policy>(transformed);
 
    Console.WriteLine(policy.PolicyNumber);
 
    foreach (var risk in policy.Risks)
    {
        Console.WriteLine(risk.RiskCode);
 
        if (risk is FooRisk)
        {
            var r = risk as FooRisk;
            Console.WriteLine(r.Name);
        }
        else if (risk is BarRisk)
        {
            var r = risk as BarRisk;
            Console.WriteLine(r.Number);
        }
    }            
}

 

System i Navigator Installer Corrupts Db Provider Factories

The IBM System i Navigator installer usually corrupts the DbProviderFactories node in the machine.config file. We have experienced this with both Version 6 and Version 7.

Possible Symptoms

  • Unable to use the¬†IBM.Data.DB2.iSeries driver. Exception mentions DbProviderFactories.
  • Cannot see all of the Data Provider options when selecting a data source in a .NET application. OLE DB and SQL Server is usually available but custom providers such as IBM.Data.DB2.iSeries is not.
  • When connecting to a Team Foundation Server Project in Visual Studio get the following Error:
    • TF31001: Cannot connect to Team Foundation Server at xyz. The server returned the following error: Configuration system failed to initialize. Retry.
  • Any error related to DbProviderFactories

The problem

The installer usually leaves a hanging closing tag in the machine.config file, which corrupts your XML. Since your app.configs/web.configs inherit from this file, your configuration is corrupted also. Re-installing does not work.

The Solution

Check the following files for corrupted XML.

  • C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\Machine.Config
  • C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config\Machine.Config

The bad XML usually, but not always, looks like this. Remove the repeating closing tags and re-start your app.

Example of a corrupted machine.config file.
System i Series Navigator installer usually corrupts the machine.config file.

Topological Sorting in C#

I found an excellent article on Topological Sorting in C#. The class is pretty easy to understand and the article is excellent.

Why is this useful? Consider a data synchronization project that needs to distribute data to various systems. The order in which jobs execute matter because reference data has dependencies on one or more master data items, at potentially different levels in the hierarchy. Having a simple SortOrder property quickly becomes insufficient and difficult to manage for large job sets.

By performing a topological sort you can get the first group of items that have no dependency, the second group which depends on the first, and so on. The problem is reduced to a statement that looks like this:

//Get the groups
var groups = TopologicalSort.Group(Jobs, x => x.DependentOn, x => x.Id);

//Sort by the SortOrder property and return the groups
return groups.Select(x => x.Select(y => y).OrderBy(z => z.SortOrder ?? 0).ToList()).ToList();

Now your admin only has to set¬†the dependency and trust that the system will find the correct execution order, in my example I added SortOrder for a little more tweaking. You as the¬†developer can now focus on more interesting topics like¬†parallel execution per group. ūüôā

Check out the article and code at:

http://www.codeproject.com/Articles/869059/Topological-sorting-in-Csharp

SharePoint REST Service Filters on Date Only, Not Time

I was recently working on a SharePoint master data management project and ran across a weird issue.

Using SharePoint’s REST services, I needed to select list items that were modified¬†after the last sync job. My query looks like this:

http://localhost/mdm/_vti_bin/ListData.svc/Contacts?$filter=Modified gt datetime'2015-08-27T23:53:00Z'

The result: 0 Rows. After¬†some¬†troubleshooting, turns out that¬†SharePoint ignores the¬†time part of the query. I had to use a “ge” (greater than or equals) operator and filter the time part in memory.

Quick search of the webs confirmed my conclusion: http://itblog.wolthaus.net/2011/12/rest-filter-datetime

This is an inconvenience because I am working on a interval-based synchronization service, it means the same data will be loaded into memory all day long for further filtering.