C#

A 11-post collection

Solved: Preventing Timeout error using XmlDocument.Load and SgmlReader

Written by Michael Earls
 programming  C#

I was working on a project that used the SgmlReader to clean up an invalid web page as I scraped data from it. I was using the System.Net.WebRequest class and related functionality.

However, because the page that I was calling used an xhtml DTD, yet included malformed xhtml in the document, it caused a timeout error when trying to load the document into an XmlDocument using the SgmlReader.

Here is my code (that caused a timeout error on line 21):

var req = WebRequest.Create("https://SomeWebsiteWithXhtmlDTDAndMalformedXhtml.com");

using (var res = req.GetResponse())  
{
  using (Stream responseStream = res.GetResponseStream())
  {
    using (StreamReader reader = new StreamReader(responseStream))
    {
      using (SgmlReader sgmlReader = new SgmlReader())
      {
        sgmlReader.DocType = "HTML";
        sgmlReader.WhitespaceHandling = WhitespaceHandling.All;
        sgmlReader.CaseFolding = Sgml.CaseFolding.ToLower;
        sgmlReader.InputStream = reader;

        // create document
        XmlDocument doc = new XmlDocument();
        doc.NameTable.Add("http://www.w3.org/1999/xhtml");
        doc.PreserveWhitespace = true;
        doc.XmlResolver = null;
        doc.Load(sgmlReader);
        return doc;
      }
    }
  }
}

Because of the malformed document (many of the tags were missing their closing tag - or specifically, one of the meta tags was missing it's ending slash. For example, rather than this:

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

it used

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Notice that the last slash is missing, making this an invalid XHTML element. Even though SgmlReader is supposed to "fix" these types of issues, it seems that the DTD was causing the issue.

The fix involved breaking out the call to the web page from the WebRequest object to using the System.Net.WebClient class to grab the page as a string and read it in that way.

Here is the replacement code.

using (WebClient client = new WebClient())  
{
  string fipsDoc = client.DownloadString("https://SomeWebsiteWithXhtmlDTDAndMalformedXhtml.com");
  fipsDoc = fipsDoc.Substring(fipsDoc.IndexOf(Environment.NewLine) + Environment.NewLine.Length);

  StringReader reader = new StringReader(fipsDoc);

  using (SgmlReader sgmlReader = new SgmlReader())
  {
    sgmlReader.DocType = "HTML";
    sgmlReader.CaseFolding = Sgml.CaseFolding.ToLower;
    sgmlReader.InputStream = reader;

    // create document
    XmlDocument doc = new XmlDocument();
    doc.PreserveWhitespace = false;
    doc.XmlResolver = null;
    doc.Load(sgmlReader);
    return doc;
  }
}

The fix is in line #4 - I simply removed the first line of code from the file. That's where the DTD was being defined. I don't know for sure why it was causing a timeout, but I'm guessing it has something to do with the fact that SgmlReader was making assumptions about the content.

I'm a bit unhappy that I had to read it in as a string, manipulate it, then pass it through a StringReader, into the SgmlReader, and finally into the document, only then to get processed by my business logic. However, this solution works for my specific use case, so I'm not going to sweat it.

Controlling a 40106 Oscillator - Part 2

Written by Michael Earls
 programming  C#  electronics  synthesizers  schematics

In past blog entries (Controlling a 40106 Oscillator from Raspberry Pi), I have covered my adventures using the 40106 CMOS chip as an oscillator to create DIY synthesizers. Since I am a beginning electronics hobbyists (and I had limited supply of parts), my circuits were imperfect and completely wrong.

My main goal for now is to control the output of 40106 oscillators using a microcontroller (like the Raspberry Pi or the Arduino).

Note: Information about using 40106 and other CMOS chips to create DIY synthesizers can be found here: Intro to "Lunetta" CMOS Synths.

You can also find an enormous amount of information on the electro-music.com DIY Synth forum

The main problem I had in the previous attempt was that I was using a NAND gate with the pinout of the Raspberry Pi on one side of the gate and the oscillator output on the other side.

Here is a pseudo-schematic of my incorrect approach:

Incorrect circuit schematic

At first glance, this seemed OK, and my circuit appeared to work when I set Pin 7 on the Raspberry Pi to HIGH. However, I was making a mistake in two places.

  • Inverted output
  • Mixed input voltages to the NAND gate

Inverted Output

A layman's explanation of how the oscillator makes sound (because I am a layman)

The 40106, when setup with a capacitor and a resistor in a "feedback loop", creates a square wave by cycling on and off at a particular frequency. If the capacitor and resistor values are chosen carefully, the frequency of the oscillation is within human hearing (~20Hz to ~20kHz). You can then hookup the output of the oscillator to an audio amplifier and hear the sound that is generated. You can also use the same setup for a low frequency oscillator (LFO) outside of the human hearing range that can be used to control other aspects of your circuit.

I read over the math behind how this works and watched a few videos on YouTube, but it makes my brain melt, so I just hack away at it. Here is a much more detailed explanation (and some great plans for a finished Lunetta oscillator bank).

Here is a picture of my oscilloscope measuring an oscillator with a square wave within an audible range.

Square Wave on oscilloscope

When the square wave hits the high point (1), it sends a HIGH signal to the output. When the square wave hits the low point, it turns the signal off.

In my original setup, I used a 470nF capacitor and a 1MΩ resistor.

Since I was using a NAND gate, the signal went HIGH when the oscillator went low. So, I was actually "hearing" the bottom of the square wave!

The fix for this was simple, I simply bought some AND gates (CD4081B - datasheet). Then the output was HIGH when both inputs were HIGH. But, there was still a mismatch in the input voltages...

Mixed Input Voltages

In the schematic, notice that pin 14 (VDD/VCC) on both ICs is connected to the +5v output of the Raspberry Pi. The entire audio circuit is running at +5v. However, when the GPIO pin on the Raspberry Pi is HIGH, it is only supplying +3.3v to the logic gate (NAND in this example). So, one side of the logic gate is getting +5v, while the other is getting +3.3v. Like I said, the circuit was working, so I was happy. Upon further study I read that for the NAND gate to register a HIGH signal, the minimum voltage at the pin must be ~5v (since our source voltage was +5v). Also, it wasn't a good idea to connect the 3.3v GPIO pins directly to a circuit running at 5v.

Logic Level Shifter

Logic level shifter

I looked around and immediately found a logic-level shifter that I could buy that would convert my 3.3v outputs to a 5v output. I decided that they were too expensive for my application (I'm going to add many more 40106 oscillators to my setup). I may end up getting a few of these down the road for more passive and simplistic applications, but they don't suit my current needs.

Update: I still need a logic level shifter. Read more details below.

Enter the i2c Port Expander

After a little more digging, I found exactly what I was looking for. The MCP23017 i2c 16 input/output port Expander allows me to communicate with the gates using i2c (there is a similar version that uses the SPI interface if that's what you prefer).

MCP23017 i2c port expander

Each chip can control up to 16 oscillators by triggering the gate. Since the MCP23017 can run at 5v with the rest of the audio circuit, it will send a 5v HIGH signal to the gate when it is triggered. This solves my problem of worrying about GPIO pins having the wrong voltages.

Here is a link to an article on Adafruit explaining how to use the MCP23017 with the Pi. While the article is a bit dated, the concepts still hold true.

MCP230xx GPIO Expander on the Raspberry Pi

From the article:

Since these io expander chips use i2c to communicate, you can power them from 5V while still connecting the i2c data lines to a 3.3V device like the pi. That's because the Pi has two i2c resistors that pull up SDA/SCL to 3.3V.

Update: It turns out that the i2c also requires level-shifting from 3.3v to 5v. The great thing is that I only need one level-shifter for all of my i2c communications.

According to the MCP23017 datasheet (pg 28), the input pins need to have a minimum voltage of 0.8 VDD, which in my case is 5v.

So, I need to be sending at least 4v to the port expander. The fact that it's working with only 3.3v is a convenient quirk. As people have pointed out in the forums, this could lead to inconsistent results and failure when using other components.

I found a great article on this very topic: Raspberry Pi and I2C devices of different voltage

Here is the circuit that I need to level shift my i2c interface:

i2c logic level shifter circuit

There is a much better description of the level shifting application at Adafruit's website. Application Note AN97055 - Bi-Directional Level Shifter for I²C-bus and other systems

Update 2016-02-15: I found the perfect bi-directional logic level shifter on Amazon. These come in a 5 pack for around $9.

XCSOURCE 5PCS IIC I2C Logic Level Converter Bi-Directional Module 5V to 3.3V TE291

Here is my final schematic showing the MCP23017 port expander connected to the oscillator and the AND gate:

Schematic of a Gated Oscillator with MCP23017

You can see that there are only two wires coming from the Raspberry Pi. These are the i2c communication wires.

Here is a picture of this circuit on a breadboard:

Gated Oscillator circuit on a breadboard

The ICs (from left to right):

  • MCP23017 - i2c I/O Port Expander
  • CD4081BE - AND Gate
  • CD40106BE - Hex inverting Schmitt trigger (used as an oscillator)

The i2c lines can be seen at the bottom left of the screen (yellow and green wire pair).

Overview video

Platform, OS, and Development environment

You can use any microcontroller that supports i2c to make this work. I am using a Raspberry Pi with Windows 10 IoT edition. My code is written using Visual Studio 2015 and C# using the Adafruit .NET Class Library. This library has a class that supports communication with the MCP23017.

Note: I found the following resources necessary to get my Raspberry Pi running Windows 10 in developer mode and making the required settings:

  • Windows 10 IoT Start Page
  • Windows 10 IoT Core Dashboard -For setting up your Raspberry Pi to run Windows 10. Also allows for software project demo installs.
  • Windows Device Portal - This helped me set up developer mode and set the debug PIN. It also allows you to access the settings of the device.
  • Windows IoT Remote Display - This is the same thing as a remote desktop client for your Windows 10 IoT devices. It allows for autodiscovery of Windows 10 IoT devices on your network. I use it when debugging my app from Visual Studio on my PC. It displays my UI on the remote client. Combined with remote debugging in Visual Studio, it ticks all the boxes for being able to effectively debug and monitor a UWP app for Windows IoT.
  • Writing Apps

Most of the information above can be found from the home page for Windows 10 IoT. When all else fails, use your favorite search engine (and then follow the link it gives you to the answer on StackOverflow...)

Here is the main source code that runs the oscillator gate. The first section is the initialization logic. It runs when the application starts up:

private async void Init()
{
  try
  {
    // prepare the I2C for communication
    _mcp = new MCP23017(0x20); // 0x20 (decimal 32) is the default address
    await _mcp.InitMCP23017Async(i2cBase.i2cSpeed.i2c_400kHz);

    for (int outputPin = 0; outputPin < 16; outputPin++)
    {
      _mcp.pinMode(outputPin, MCP23017.Direction.OUTPUT);
    }

    PerformOutputTest();
  }
  catch (Exception ex)
  {
    string a = ex.Message;
  }
}

Once the initialization has occurred, the user interface loads up toggle switches. When the state of a toggle switch changes, it fires an event that determines the output pin based on the number of the toggle switch. Here is the toggle event handler:

private async void toggleSwitch_Toggled(object sender, RoutedEventArgs e)
{
  var toggle = e.OriginalSource as ToggleSwitch;
  int outputPin = Int32.Parse(toggle.Name.Substring(Utility.TOGGLE_SWITCH_PREFIX.Length));

  MCP23017.Level toggleState = toggle.IsOn ? MCP23017.Level.HIGH : MCP23017.Level.LOW;

  try
  {
    _mcp.digitalWrite(outputPin, toggleState);
  }
  catch (Exception ex)
  {
    string a = ex.Message;
  }
}

The way I've implemented the handler, I have to take care to ensure that my toggle switch naming convention is handled correctly. In my case, I defined a constant value in a static utility class that I use to determine the name of the toggle switch.

Related: MCP23017 Class reference on Adafruit.com

Here is the definition of the prefix constant that is in my Utility class:

public const string TOGGLE_SWITCH_PREFIX = "toggleSwitch";

I have also named my toggle switches using this prefix and the target output pin that I want to flip when the switch state changes:

<ToggleSwitch 
  x:Name="toggleSwitch0" 
  Header="Gate 1" 
  HorizontalAlignment="Left" 
  Margin="10,65,0,0" 
  VerticalAlignment="Top" 
  Toggled="toggleSwitch_Toggled" 
  IsDoubleTapEnabled="False" 
  IsHoldingEnabled="False"  
/>

Here is what my user interface looks like on the Raspberry Pi:

When the user toggles the switch, the associated pin goes HIGH on the MCP23017, which causes the AND gate to toggle its output (pin 3 in this case) to HIGH each time the 40106 square wave goes HIGH. This output is then sent to the output pin (SIGNAL_OUT on the right side of the schematic), where it can be used by another circuit (an audio amplifier in this case).

Conclusion

After a few false starts, I believe that I have the gating mechanism that I can use to control most of my synth circuits. I anticipate that I'll also use this approach to turn effects on and off, as well as other applications (enabling/disabling control voltages (CV signals)).

Windows 10 IoT is Ready for Prime Time

I used Linux (Raspbian) and Mono .NET in my previous attempts at this effort. While it worked, it didn't feel comfortable. Things were off somehow.

I decided to switch to Windows 10 IoT. The Windows IoT ecosystem is absolutely brilliant. It was a little bit of a technical challenge getting things to work the first time, but everything performed exactly as it should have. The learning curve should be easy for most .NET developers and slightly challenging for non .NET developers. There were no strange errors or undocumented secrets to getting things to work.

The tools they provide "just work". I was able to get a remote shell on my Pi using PowerShell. I easily accessed my Pi using the IoT remote desktop app. It's easy to setup your custom app to always launch as the default app when the device starts. Add to that the fact that I can use Visual Studio 2015 (the IDE and development environment I use at work each day) to develop these apps and you have a great end-to-end solution. I haven't yet integrated with Azure IoT hub or any of the cloud features yet, but I have read up on them and know they could come in handy later for home automation and other applications.

Another great discovery was that Adafruit has created the .NET NuGet package (and related GitHub project). This made it very easy to interface with the MCP23017

Thanks go out to Rick Lesniak for his excellent work on this library. He saved me hours of work.

Footnote: I made videos describing each of the topics discussed in this post. I have not yet had the time to combine them into one video. Once I get it created and edited, I will embed it here and post a link to it on my social media sites.

Better property names using the DataMember attribute

Written by Michael Earls
 development  json  C#  .NET  serialization

In my previous post, I demonstrated creating a class to serialize the data returned from the Lipsum.com JSON feed. I wasn't happy with the final result as it used JavaScript formatting for the property names (camel cased).

I prefer Pascal casing on my object properties in C#, so I wanted to quickly show how to change the name of the property on the class.

Here is the new LoremIpsum class definition:

public class LoremIpsum
{
    public Feed Feed { get; set; }
}

[DataContract]
public class Feed
{
    [DataMember(Name ="lipsum")]
    public string Lipsum { get; set; }

    [DataMember(Name = "generated")]
    public string Generated { get; set; }

    [DataMember(Name = "donatelink")]
    public string DonateLink { get; set; }

    [DataMember(Name = "creditlink")]
    public string CreditLink { get; set; }

    [DataMember(Name = "creditname")]
    public string CreditName { get; set; }
}

You'll first need to add a reference to System.Runtime.Serialization to your project. Then, include the System.Runtime.Serialization namespace in your using declarations.

The main() method now looks like this:

static void Main(string[] args)
{
    for (int i = 0; i < 10; i++)
    {
        // toggle between words and paragraphs
        bool isEven = (i % 2).Equals(0); // used this because markdown had trouble with double equal signs
        bool isThird = (i % 3).Equals(0);
        LipsumType lipsumType = isEven ? LipsumType.Paragraphs : LipsumType.Words;

        // only start with Lorem Ipsum every third call
        Debug.WriteLine(LoremIpsumUtil.GetNewLipsum(lipsumType, 7, isThird).Feed.Lipsum + Environment.NewLine);

        // sleep for 1 second to give the server a rest
        Thread.Sleep(1000);
    }
}

The main difference is that now, we use LoremIpsumUtil.GetNewLipsum(lipsumType, 7, isThird).Feed.Lipsum.

As you can see, our properties are now Pascal cased, so they look more in line with what you'll see throughout the other .NET libraries.

Getting filler text from the Lipsum.com REST API

Written by Michael Earls
 development  programming  C#  json  lorem ipsum

I had the need to generate some random filler text for a bunch of records today, and I wanted to use the Lorem Ipsum latin text. Normally, I use the great website Lipsum.com and fill out the form and hit submit. Then, I copy the text provided into my destination.

(This project (reusable .NET class library and sample app) can be found on GitHub at https://github.com/cerkit/LoremIpsum/)

However, I needed to automate this process, so I did a little poking around. It turns out that the lipsum.com website exposes a json feed that can be altered based on your needs.

Note: Using the Lipsum website in this manner is placing stress on their web server. As such, I highly suggest using the donate link provided within the data set that is returned to provide them with a little money to support your efforts.

I wrote my code in such a way as to limit the call rate to one call per second. It took a lot longer to insert my records than I wanted, but I felt sure I wasn't putting unneeded strain on their servers.

The main endpoint for accessing the default data set is: http://lipsum.com/feed/json.

This will give you the following results:

{
    feed: {
        lipsum: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras tristique massa eu porttitor aliquam. Vivamus sodales sit amet nulla nec volutpat. Sed accumsan iaculis turpis, maximus sagittis ipsum tincidunt et. Cras ac velit eu quam cursus lobortis sit amet vitae quam. Donec nec odio at ligula porttitor viverra nec eu est. Praesent non quam ipsum. Curabitur vitae scelerisque augue. In sed elementum velit. Donec lacinia ut leo a porttitor. Phasellus nec risus placerat, pulvinar ante euismod, tempus lacus. Nam turpis velit, accumsan eget placerat porttitor, hendrerit vitae tortor. Vivamus posuere leo elit, at pretium justo imperdiet id. Duis finibus ante vel mollis rhoncus. Donec sollicitudin sed tortor vulputate bibendum. Aenean tincidunt nisi sed libero sollicitudin, in interdum erat efficitur. Phasellus porttitor faucibus risus non consectetur. Nam a sollicitudin erat, ut lacinia leo. Praesent convallis odio orci, a iaculis lacus viverra non. Maecenas consequat, risus nec egestas consectetur, tellus tellus condimentum mi, in suscipit metus sem quis velit. In a lorem semper, tincidunt mauris a, blandit erat. Aliquam non auctor tortor, et mattis nibh. Aenean at magna at diam commodo feugiat sit amet ut erat. Nunc hendrerit tempus imperdiet. Phasellus varius id justo non vestibulum. Ut quis mollis mauris. Aliquam egestas arcu non erat congue, id ornare elit molestie. Pellentesque rutrum nunc sed arcu semper mollis. Proin malesuada tristique quam quis luctus. Nunc dignissim, orci vitae rhoncus porta, orci enim accumsan urna, ut egestas metus lectus id turpis. Sed in nisi ligula. Etiam sodales est arcu, vitae dignissim metus blandit id. Aenean leo velit, blandit sit amet ex vel, vestibulum ornare ipsum. Donec rutrum euismod velit, ac fringilla leo iaculis ornare. Duis a eros id odio aliquet vestibulum quis vel est. Sed ultricies ac sapien sed tincidunt. Integer bibendum turpis at nisl venenatis facilisis. Morbi sodales dignissim lectus, non sagittis purus cursus dignissim. Phasellus aliquam elementum venenatis. Nunc sed pharetra purus, id blandit velit. In sed massa consequat, posuere nulla non, rhoncus orci. Maecenas a consequat lorem. Morbi sit amet quam felis. Sed at posuere metus. Morbi vestibulum nisl id massa euismod malesuada. Aenean accumsan, elit eu finibus pellentesque, elit metus faucibus tellus, non interdum lacus massa ut velit. Suspendisse fermentum elit sed ipsum luctus consequat. Suspendisse potenti. Aenean sagittis lorem augue, quis condimentum velit facilisis eu. Vivamus posuere ante sed porta fringilla. Morbi pharetra lorem id urna iaculis cursus. Pellentesque at arcu vel lacus euismod accumsan. Sed pretium turpis odio, id tincidunt nisi blandit nec. Suspendisse non ornare massa. Proin facilisis porta dolor nec vestibulum. Aenean accumsan pulvinar magna, in auctor odio tempor eget. Morbi in rutrum quam. Fusce quis ipsum augue. Duis et ligula ut tellus sollicitudin rutrum sit amet eget nisi. Duis id est sit amet orci venenatis consectetur et eget ipsum.",
        generated: "Generated 5 paragraphs, 454 words, 3017 bytes of Lorem Ipsum",
        donatelink: "http://www.lipsum.com/donate",
        creditlink: "http://www.lipsum.com/",
        creditname: "James Wilson"
    }
}

I decided to take a look at the source code for the home page and get an idea of the form names that are used to set the options for the feed.

I found the following query string arguments

  • what: valid values = paras, words, bytes, and lists
  • amount: the amount of the chosen type to return (the minimum value is 5 for words)
  • start: yes or no depending on whether or not you want to start with "Lorem Ipsum". If set to no, you'll get a random return value.

So, I wrote my program to loop through the days in the current year and insert a record for each day, adding the random "lipsum" text to the record.

Here's a quick C# program that will use the Newtonsoft.Json library to deserialize the lipsum result into an object that you can use in your code.

This assumes that you're using Visual Studio (community or professional edition).

First, visit the following url: http://lipsum.com/feed/json?amount=5&start=no&what=words

Now, view the source of the results and copy them to your clipboard. Start a new project in Visual Studio (if you don't already have one open) and then create a new class. Name the file LoremIpsum.cs.

It will generate the following code:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;

namespace LoremIpsum  
{
    class LoremIpsum
    {
    }
}

Delete the class LoremIpsum that it generated (but keep the rest of the file).

Click inside the namespace and choose Edit->Paste Special->Paste JSON as Classes from the main menu.

This will insert classes that are compatible with the lipsum data. Rename the Rootobject class to LoremIpsum. Your code should look like the following (LoremIpsum.cs):

namespace LoremIpsum  
{
    public class LoremIpsum
    {
        public Feed feed { get; set; }
    }

    public class Feed
    {
        public string lipsum { get; set; }
        public string generated { get; set; }
        public string donatelink { get; set; }
        public string creditlink { get; set; }
        public string creditname { get; set; }
    }

}

Now, we will need to fetch the data and deserialize it into an object we can use.

Before we continue, make sure you have a reference to the Newtonsoft.Json library. You can use nuGet to install it easily.

First, we'll define an enum to represent the result types:

public enum LipsumType  
{
    [Description("words")]
    Words,
    [Description("paras")]
    Paragraphs,
    [Description("bytes")]
    Bytes,
    [Description("lists")]
    Lists
}

Notice that I used the System.ComponentModel.Description attribute on each of the enum values to represent the values that need to get sent to the api. This will come in handy later.

Here is a generic extension method on enums that will return the description (this works on any enum containing values decorated with the System.ComponentModel.DescriptionAttribute class):

public static string GetDescription(this T e) where T : IConvertible  
{
    Array values = System.Enum.GetValues(e.GetType());
    string description = null;

    foreach (int val in values)
    {
        if (val == e.ToInt32(CultureInfo.InvariantCulture))
        {
            var type = e.GetType();
            var memInfo = type.GetMember(Enum.GetName(type, val));
            var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            description = ((DescriptionAttribute)attributes[0]).Description;
        }
    }

    return description;
}

Now, let's move on to the actual web call:

public static readonly string LIPSUM_JSON_URL = "http://lipsum.com/feed/json?amount={0}&start={1}&what={2}";

public static LoremIpsum GetNewLipsum(LipsumType lipsumType, int amount, bool startWithLoremIpsum = true, ICredentials proxyCredentials = null)  
{
    string requestUrl = string.Format(LIPSUM_JSON_URL, amount, startWithLoremIpsum ? "yes" : "no", lipsumType.GetDescription());

    HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;

    if (proxyCredentials != null)
    {
        request.Proxy.Credentials = proxyCredentials;
    }

    using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
    {
        if (response.StatusCode != HttpStatusCode.OK)
            throw new Exception(String.Format(
            "Server error (HTTP {0}: {1}).",
            response.StatusCode,
            response.StatusDescription));

        StreamReader sr = new StreamReader(response.GetResponseStream());
        JsonTextReader tr = new JsonTextReader(sr);
        JsonSerializer ser = new JsonSerializer();

        return ser.Deserialize(tr);
    }
}

In the requestUrl definition, I used the LipsumType.GetDescription() extension method that I defined earlier to send the correct type based on what was chosen by the caller.

Don't forget to use the using() {} when dealing with an object that implements IDisposable. It will clean up after you and prevent you from leaving any machine resources open.

Notice the use of the ser.Deserialize<LoremIpsum>() call (GitHub source). I was able to do this because we created a class directly from the JSON data. We then use this class with the Json (de)serializer to get an instance of the LoremIpsum class containing the results of our call.

Here is the main() method of the program that ties it all together:

static void Main(string[] args)
{
    for (int i = 0; i < 10; i++)
    {
        // toggle between words and paragraphs
        bool isEven = (i % 2) == 0;
        bool isThird = (i % 3) == 0;
        LipsumType lipsumType = isEven ? LipsumType.Paragraphs : LipsumType.Words;

        // only start with Lorem Ipsum every third call
        Debug.WriteLine(LoremIpsumUtil.GetNewLipsum(lipsumType, 7, isThird).feed.lipsum + Environment.NewLine);

        // sleep for 1 second to give the server a rest
        Thread.Sleep(1000);
    }
}

This simply loops 10 times and makes a call to the lipsum.com json endpoint, toggling between paragraphs and words, as well as starting with "Lorem Ipsum" every third call. It also waits one second between each call to be friendly to the server.

Because we get back a fully populated object, we can also access the other properties on the LoremIpsum instance, like *.feed.generated and *.feed.donatelink.

Update: I've written a post that describes how to get PascalCased property names.

Decorating an enum with the Description attribute for later use in C# with .NET

Written by Michael Earls
 .NET  C#

I had the need today to set a string value based on the value of an enum. Rather than creating the following code:

Edit: I added a generic method that works on all enums

string myString = null;  
switch(myEnum)  
{
    case myEnum.Value1: 
        myString = "value 1"; 
        break; 
    case myEnum.Value2: 
        myString = "value 2"; 
        break; 
    case myEnum.Value3: 
        myString = "value 3"; 
        break; 
}

I wanted to do something simpler. So, I decided to add the System.ComponentModel.Description attribute to my enum, like so:

using System.ComponentModel; 

public enum MyEnum  
{ 
    [Description("value 1")] 
    Value1, 
    [Description("value 2")]
    Value2, 
    [Description("value 3")]
    Value3
}

Then, to make it easy to use, I added an extension method to all enums:

public static string GetDescription<T>(this T e) where T : IConvertible  
{
    string description = null;

    if (e is Enum)
    {
        Type type = e.GetType();
        Array values = System.Enum.GetValues(type);

        foreach (int val in values)
        {
            if (val == e.ToInt32(CultureInfo.InvariantCulture))
            {
                var memInfo = type.GetMember(type.GetEnumName(val));
                var descriptionAttributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
                if(descriptionAttributes.Length > 0)
                {
                    // we're only getting the first description we find
                    // others will be ignored
                    description = ((DescriptionAttribute)descriptionAttributes[0]).Description;
                }

                break;
            }
        }
    }

    return description;
}

This will allow you to easily get the description of the current enum value. Here is how you would do that:

string description = null;  
MyEnum testEnum = MyEnum.Value2;  
description = testEnum.GetDescription(); // description will be "value 2"

As you can see, it’s pretty easy to decorate your enum values with string descriptions. This allows you to have a central location to set the value.

I can even see a custom description attribute class that retrieves the description from a database. The use cases are there.

Another, more common use case for this method is to localize the values returned by using resource files representing the languages you want to display. You could have one for en-US, en-GB, es-ES, es-MX, etc, using the description Name as the key to the resource file.

Project changes! More C# posts to come

Written by Michael Earls
 C#  VB.NET

After a meeting this morning, we have decided to go with ASP.NET 5 and C#, rather than ASP.NET 4.5.2 and Visual Basic .NET. So, my technical posts will switch back to C#.

I’m pretty excited about the change. I had the base framework completed in VB, but that would have ensured that my client would be stuck in the near future as Microsoft is not supporting VB in the next version of ASP.NET.

Now, the dilemma is whether or not to use AngularJS. :)

Of "old versus new" - Why not AngularJS? Why ASP.NET?

Written by Michael Earls
 AngularJS  C#  VB.NET  WebForms

I recently commented on a friend’s Facebook post about AngularJS stating that I hoped Angular dies a quick and horrible death. I guess that was a bit harsh, but I have to admit that I’m tired of reading about it. To be fair, I have created an Angular app that used routing, controllers, basic authentication, WebAPI, and messaging, so I do have some experience with it. I liked it, it was nice, and the architecture is sound.

I don’t understand why people are abandoning ASP.NET for SPA (Angular in particular). Are postbacks really that bad? The AJAX-style communication with the server is overrated in my book. If you build a good user interface and have a decent connection, then Angular and ASP.NET should take the same amount of time. Front-loading JS libraries or waiting for the server to respond take the same amount of effort. And, you are more kind to a larger install base of browsers. Angular takes a somewhat arrogant approach to browsers in that it only works on the latest. It is unapologetic about this.  I see much the same attitude from developers of Angular apps, as well. They seem to state that “if you don’t use the latest technology to access my app, then I have no time for you. I’ll be damned if I’m going to use that ‘old’ technology”. Not everyone is like this, but I have seen this attitude on some posts.

Simply using a technology because it’s new is not a good enough reason for me. When I developed my Angular JS app, I immediately saw where I was going to have trouble maintaining it in the future. Upgrades would require a complete rewrite and changes to the structure would require the same architectural challenges as any other technology.

I have Dependency Injection in my current application to help with dependencies, but with Entity Framework being the core of my data story, I don’t have a whole lot of trouble getting to what I need.

In the end, I think it comes down to your comfort level with using “old” technology. In my eyes, it’s a sign that it is tried and true. Just because something is new doesn’t mean it is better. However, looking at it from another angle, there are many new features being added to ASP.NET these days that make life a lot easier for the developer and make the application more efficient.

Of course, you’ll probably be reading another AngularJS post in the future where I’ve decided to use it after all and I couldn’t imagine using anything else.  Maybe for my next project. But for now, I must work with WebForms and VB.NET.

Calling DataBind() on a GridView within an UpdatePanel to handle a row delete command

Written by Michael Earls
 .NET  ASP.NET  C#  VB.NET

I was working on maintaining a site that used a GridView within an UpdatePanel and had difficulties with the DataBind() call. I added a delete button (using a CommandField) to the grid and wired up the command logic to delete from a generic list that I was keeping up with. The grid was bound to the List. It just wasn’t updating the contents of the Grid when I removed records from the source.

It turns out that when I added the Delete command, I was also supposed to handle the OnRowDeleting event. I didn’t receive an error message to let me know this until I removed the UpdatePanel and tried it again. Once I added the handler for the event, it worked just fine. So I added the UpdatePanel back and everything now works as it should.