Thursday, May 31, 2012

bolt declared variables onto a table returned in SQL

The last line of the stored procedure should change from this:

select * from #Baz

 
 

To this:

select @Foo as Foo, @Bar as Bar, * from #Baz

 
 

#Baz will come back to you with two extra columns. An extra column will hold the same value over and over again in each row.

SET IDENTITY_INSERT

If you get this error message in SQL:

Msg 544, Level 16, State 1, Line 1 Cannot insert explicit value for identity column in table 'YOURTABLENAMEHERE' when IDENTITY_INSERT is set to OFF.

 
 

I think the thing to do is something like this:

SET IDENTITY_INSERT YOURTABLENAMEHERE ON

Monday, May 28, 2012

Clear the browsing history on your iPhone.

At: Settings > Safari > Clear History

QR codes

You can get app for your iPhone that will scan these. They contain a URL. That is the information they hold. Your scanning app will likely redirect you there.

Sunday, May 27, 2012

red/black trees

C# 4.0 in a Nutshell mentions a red/black tree on page 290. To that end I thought I'd look up trees at wikipedia. Of trees:

  1. The left subtree of a node contains only nodes with keys less than the node's key.
  2. The right subtree of a node contains only nodes with keys greater than or equal to the node's key.
  3. Both the left and right subtrees must also be binary search trees.

 
 

red/black trees

  1. A node is either red or black.
  2. The root is black. (This rule is sometimes omitted from other definitions. Since the root can always be changed from red to black, but not necessarily vice-versa, this rule has little effect on analysis.)
  3. All leaves are the same color as the root.
  4. Both children of every red node are black.
  5. Every simple path from a given node to any of its descendant leaves contains the same number of black nodes.

 
 

The red/black thing is basically a constraint on how a tree is shaped.

Note: a leaf is a node with no children

Saturday, May 26, 2012

Array.ConvertAll shows off the power of delegates.

I wonder if the Visitor Pattern more or less works in this manner. TryToGiveGermanNameForSingleDigit below is the same thing it is here save for the the method is public instead of private. This test passes:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Whatever.Models;
namespace Whatever.Tests
{
   [TestClass]
   public class ConvertAllTests
   {
      [TestMethod]
      public void Test()
      {
         Int16[] digits = new Int16[] {2, 7, 8, 9};
         string[] conversion = Array.ConvertAll(digits,
               Foo.TryToGiveGermanNameForSingleDigit);
         Assert.AreEqual(conversion.Length, 4);
         Assert.AreEqual(conversion[0], "zwei");
         Assert.AreEqual(conversion[1], "sieben");
         Assert.AreEqual(conversion[2], "acht");
         Assert.AreEqual(conversion[3], "neun");
      }
   }
}

Friday, May 25, 2012

ICANN governs registries

InterNIC gave way to ICANN which manages top level domain names and assignments of address blocks to registries.

 
 

Addendum 5/14/2018: InterNIC used to tell you what domain name pointed where before everyone started using routers to crowdsource as much.

 
 

Addendum 7/20/2019:The NIC part of InterNIC stood for Network Information Center and ICANN is Internet Corporation for Assigned Names and Numbers.

Predicate Delegates

Predicate<T> is a delegate that takes in T and then returns true of false. A predicate could, for example, consume a string and then return whether or not the copy came after the word "Cat" alphabetically. This bit of knowledge comes from Chapter 7 of "C# 4.0 in a Nutshell" which is a good read.

Thursday, May 24, 2012

The Track Changes feature in Microsoft Word is found in the Review tab.

This is where "Spelling & Grammar" is found too.

query execution failed for dataset

I got this error in attempting to run an SSRS report:

  • An error has occurred during report processing. (rsProcessingAborted)
  • Query execution failed for dataset 'Whatever'. (rsErrorExecutingCommand)
  • For more information about this error navigate to the report server on the local server machine, or enable remote errors

 
 

It didn't happen for all reports in a project. Rather, it happened for all but one report. One report worked just fine. This led me to believe that there wasn't anything wrong with the data source that was set up. The reports that were handed to me that wouldn't work were supposedly legit. What was messed up? It turned out that the queries in all but one of the reports reached into views which did joins out to another database. The user at the data source just needed its permissions updated to be able to "see" into the other database. I did not solve this problem via enabled remote errors. :P

Wednesday, May 23, 2012

shock collars

New Iron's Janelle Klein hosted a roundtable discussion at Lean Software Austin on Monday. The topic was on mistake-proofing.

The discussion was framed such that we were to talk about what are and how to implement shock collars in lieu of Tupperware's Shape-o-balls. Let me explain the difference. Janelle envisioned two forms of mistake-proofing while putting discussion emphasis on the latter of the two. Janelle's two varieties of mistake proofing:

  1. Shape-o-balls only allow you to put pieces in the holes made to accommodate those pieces. This is simply an analogy for software that is restrictive in a healthy way. (i.e. well architected)
  2. Shock Collars in contrast don't prevent you from making a mistake. They signal you when you are about to stray outside of the invisible fence of good practice letting you know that you're about to be walking into PAIN, PAIN, PAIN. Now what do these look like? Are these tests asserting how things should be? The group brought this up and then quickly dismissed it. One could stray into pain and have tests reinforcing the course of action the entire time. With tests ruled out it quickly seemed like shock collars were in fact not of an engineering solution but instead of environment and culture and hence naturally more fuzzy in definition. Janelle seemed to suggest that a good culture could serve as a shock collar the same way a good upbringing might discourage one to lie/cheat/steal.

The event started at 6:30 in the evening and I left a little after 9. The discussion lasted later into the night, but by the time I left there had been much productive discussion yet not a single example of a shock collar offered. The group wrestled with the topic. Many suggested that cultural solutions lay in crafting an environment that empowered persons to do well in contrast to shocking them before they do bad. One attendee suggested: "There is nothing you can do to make a plant grow as a gardener. All you can do is create an environment where a plant can grow." Scott Bellware who runs Lean Software Austin suggested that geeks will respond poorly to negative enforcement (compared to positive enforcement) as so many have historically fit the stereotype of being that guy bullied by the jocks in high school. Another attendee suggested in contrast that geeks will respond negatively to negative enforcement due to histories of being the smart guys who usually come out on top in academic completion and are used to winning and having their ways.

The thing I took away from the meeting is that we shouldn't try to be making others wear shock collars, and yet, I can think of so many times when I've been ahead for telling myself "Com'on stupid, you need to be doing better." Yet, there is a big difference between browbeating yourself and either browbeating others or having them browbeat you. It was an interesting talk. It was just understandably hard for the group to put its finger on a consensus for recommending any concrete shock collar-based solutions. Steering our culture seems challenging stuff... worthy of debate!

Tuesday, May 22, 2012

There are two different things to think about for column ordering in SharePoint 2010.

  1. In the "List" subtab beneath the "List Tools" tab there is an option for "List Settings" and if one clicks here and then clicks the link for "Column ordering" one may change the order form fields appear for editing columns at CRUD screens for list line items.
  2. In the "List" subtab beneath the "List Tools" tab there is an option for "Modify View" and if one clicks here one may alter the order columns appear in at a list.

Sunday, May 20, 2012

Process

More cool stuff from Chapter 5 of C# 4.0 in a Nutshell: Process! The first test below will open up a file in the Notepad. The second test will reach into a command line shell and then pull out the copy given when one types ipconfig. The book suggests the shell itself will be suppressed with the "UseShellExecute = false" stuff, but on my end I see shell flicker open and then close really quickly. Whatever. Neat stuff. Use Process to reach out to other apps on your PC from C#! Hell yes!

using System.Diagnostics;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Whatever.Tests
{
   [TestClass]
   public class ProcessTests
   {
      [TestMethod]
      public void NotepadTest()
      {
         TextWriter writer = new StreamWriter("C:\\Tom.txt");
         writer.Write("Hello World");
         writer.Close();
         Process.Start("Notepad.exe", "C:\\Tom.txt");
         TextReader reader = new StreamReader("C:\\Tom.txt");
         string whatWasRead = reader.ReadToEnd();
         reader.Close();
         Assert.AreEqual(whatWasRead, "Hello World");
      }
      
      [TestMethod]
      public void CommandLineTest()
      {
         ProcessStartInfo processInfo = new ProcessStartInfo();
         processInfo.FileName = "cmd.exe";
         processInfo.Arguments = "/c ipconfig /all";
         processInfo.RedirectStandardOutput = true;
         processInfo.UseShellExecute = false;
         Process process = Process.Start(processInfo);
         string ipInfo = process.StandardOutput.ReadToEnd();
         Assert.IsTrue(ipInfo.Contains("192.168.1.65"));
      }
   }
}

How do I get more than one thing back from a method?

Boy, this is a pain point isn't it? I've heard Eric Hexter use a Mad Max Beyond Thunderdome analogy: "Two go in, one comes out" ...and while it doesn't have to be just two things in a method's signature, you are just getting one thing back at the end of it all. This is an adjustment for all of us who learned object-oriented programming, and sometimes we try to fight it by using ref and out variables. Boo. It is probably best to try your damnedest to stick with writing readable code in which methods just give back one thing. C# 4.0 in a Nutshell, a book I am reading, mentions that Tuples are a new object type in C# 4.0 that allow you to have a grab bag of dissimilar types balled up in one type that may then be unspooled on the other side of being handed back by a method. This sort of hack already existed somewhat with KeyValuePair exploits, but a Tuple will allow one to hand back up to seven dissimilar things instead of merely two. I've never yet seen anyone's code use a Tuple so I suspect that this is coming to us too late after we have all learned our own dirty tricks for fighting with "one comes out." Test tests below pass and show off tucking stuff into a Tuple and pulling it back out again.

using System;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Whatever.Tests
{
   [TestClass]
   public class TupleTest
   {
      [TestMethod]
      public void Test()
      {
         DateTime today = new DateTime(2012, 5, 20);
         Random random = new Random(14);
         StringBuilder book = new StringBuilder();
         book.Append("Call me Ishmael.");
         Tuple<DateTime, Random, StringBuilder> grabBag = Tuple.Create(today, random,
               book);
         Assert.AreEqual(grabBag.Item1.Year, 2012);
         Assert.IsTrue(grabBag.Item2.NextDouble() >= 0 && grabBag.Item2.NextDouble() <
               14);
         grabBag.Item3.Append(" Some years ago - never mind how long precisely - ");
         Assert.AreEqual(grabBag.Item3.ToString(), "Call me Ishmael. Some years ago -
               never mind how long precisely - ");
      }
   }
}

Istanbul (Not Constantinople)

Chapter five of C# 4.0 in a Nutshell goes into globalization and localization and illustrates that the local culture is driven from the control panel of the PC at hand (or I suppose from elsewhere on other operating systems) and that one may overpower this setting in code as shown below. The book suggests that Turkey is a good country to use when testing if what you are doing supports globalization. DateTime values are formatted wildly differently from the norm and when using .ToUpper() in lieu of .ToUpperInvariant() there can be some more wackiness. The tests below pass.

using System;
using System.Globalization;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Whatever.Tests
{
   [TestClass]
   public class ThreadTest
   {
      [TestMethod]
      public void TestForTexas()
      {
         string currentCulture = Thread.CurrentThread.CurrentCulture.TextInfo.ToString();
         DateTime today = new DateTime(2012, 5, 20);
         Assert.AreEqual(currentCulture, "TextInfo - en-US");
         Assert.AreEqual(today.ToString(), "5/20/2012 12:00:00 AM");
         Assert.AreEqual("i".ToUpper(), "I");
         Assert.AreEqual("I".ToLower(), "i");
      }
      
      [TestMethod]
      public void TestForTurkey()
      {
         Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("tr-TR");
         string currentCulture = Thread.CurrentThread.CurrentCulture.TextInfo.ToString();
         DateTime today = new DateTime(2012, 5, 20);
         Assert.AreEqual(currentCulture, "TextInfo - tr-TR");
         Assert.AreEqual(today.ToString(), "20.05.2012 00:00:00");
         Assert.AreEqual("i".ToUpper(), "İ");
         Assert.AreEqual("I".ToLower(), "ı");
         Assert.AreEqual("i".ToUpperInvariant(),"I");
         Assert.AreEqual("I".ToLowerInvariant(), "i");
      }
   }
}

Saturday, May 19, 2012

using string.Format with flags enums

Page 231 of "C# 4.0 in a Nutshell" illustrates that one may use string.Format to get back a string representation of the values of a flags enum!

using Microsoft.VisualStudio.TestTools.UnitTesting;
using Whatever.Models;
namespace Whatever.Tests
{
   [TestClass]
   public class BorderTests
   {
      [TestMethod]
      public void Test()
      {
         Border border = Border.Top | Border.Left;
         Assert.AreEqual((int)border, 4 + 1);
         string combination = string.Format("{0:F}", border);
         Assert.AreEqual(combination,"Left, Top");
      }
   }
}

 
 

Here is a flags enum:

using System;
namespace Whatever.Models
{
   [Flags]
   public enum Border
   {
      Left=1,
      Right=2,
      Top=4,
      Bottom=8
   }
}

using IFormatProvider and ICustomFormatter

On page 224 of "C# 4.0 in a Nutshell" I found some puzzling code. It is given again here. I typed it up and got it working.

using System;
using System.Globalization;
using System.Text;
namespace Whatever.Models
{
   public class WordyFormatProvider : IFormatProvider, ICustomFormatter
   {
      private static readonly string[] _numberWords = "zero one two three four five six seven
            eight night minus point".Split();
      
      private IFormatProvider _parent;
      
      public WordyFormatProvider() : this(CultureInfo.CurrentCulture) {}
      public WordyFormatProvider (IFormatProvider parent)
      {
         _parent = parent;
      }
      
      public object GetFormat (Type formatType)
      {
         if (formatType == typeof(ICustomFormatter)) return this;
         return null;
      }
      
      public string Format (string format, object arg, IFormatProvider prov)
      {
         if (arg == null || format != "W") return string.Format(_parent, "{0:" + format + "}",
               arg);
         StringBuilder result = new StringBuilder();
         string digitList = string.Format(CultureInfo.InvariantCulture, "{0}", arg);
         foreach (char digit in digitList)
         {
            int i = "0123456789-.".IndexOf(digit);
            if (i == -1) continue;
            if (result.Length > 0) result.Append(' ');
            result.Append(_numberWords[i]);
         }
         return result.ToString();
      }
   }
}

 
 

Alright, the GetFormat method isn't really used in the book's example, but Visual Studio will put a red squiggly beneath IFormatProvider in line six above without it. (IFormatProvider requires it.) I didn't realize this until I typed up the code. Also Visual Studio will show a red squiggly below ICustomFormatter if the Format method, which we test below, is not there. (ICustomFormatter requires it.) What does this thing do? It allows you to cast a number to a series of words like so:

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Whatever.Models;
namespace Whatever.Tests
{
   [TestClass]
   public class WordyFormatProviderTests
   {
      [TestMethod]
      public void Test()
      {
         double number = -1.5;
         IFormatProvider formatProvider = new WordyFormatProvider();
         string formattedNumber = string.Format(formatProvider, "{0:W}", number);
         Assert.AreEqual(formattedNumber, "minus one point five");
      }
   }
}

 
 

I tried to remove ICustomFormatter from line six of WordyFormatProvider, but then I got this error at line fourteen of WordyFormatProviderTests:

Unable to cast object of type 'Whatever.Models.WordyFormatProvider' to type 'System.ICustomFormatter'.

 
 

It is hard to see the dependency on ICustomFormatter. string.Format apparently needs it associated with an object of IFormatProvider type as shown here. I thought my head was gonna explode.

an interesting refactoring

super overkill method testing on Twitpic

I undertook an interesting refactoring at work. We have a legacy app that feels like it was written in VS2005 and C# 2.0 and then was at some point upgraded to VS2010 and C# 4.0. The app is of web forms and had no tests prior to my touch. It has the sort of fat classes that I hate as they are impossible to roll tests into. I once saw Eric Anderson speak on how to spruce up an legacy code base and make it maintainable and he suggested trying to start by raising an island out of the ocean of bad. That which is above water is that which is under test. Once you have an island, hopefully you can grow it. I started by pulling all of the getsetters that governed user permissions out of the User class which was unfortunately more than a POCO into a class called UserPermissions which then was a POCO and easy to test.

namespace Whatever.Core
{
   public class UserPermissions
   {
      public bool ActiveUser { get; set; }
      public bool ManagementReportViewer { get; set; }
      public bool CanSelectTimeEntry { get; set; }
      public bool CanSelectActivity { get; set; }
      public bool CanAddContractingAction { get; set; }
      public bool CanSubmitContractingAction { get; set; }
      public bool IsDivisionPoc { get; set; }
      public bool IsDivisionManager { get; set; }
      public bool IsDivisionAdmin { get; set; }
      public bool IsAdmin { get; set; }
      public bool IsTTUser { get; set; }
      public bool IsTTUserForProjectEntry { get; set; }
      public bool IsTTUserForSummaryEntry { get; set; }
      public bool IsProjectEntryUser { get; set; }
      public bool IsABCAdmin { get; set; }
      public bool IsABCPOC { get; set; }
      public bool IsABCViewer { get; set; }
      public bool IsTech { get; set; }
      public bool IsContact { get; set; }
      public bool IsContributor { get; set; }
      public bool IsProd { get; set; }
      public bool IsIso { get; set; }
      public bool IsContractingOfficer { get; set; }
      
      public UserPermissions()
      {
         ActiveUser = false;
         ManagementReportViewer = false;
         CanSelectTimeEntry = false;
         CanSelectActivity = false;
         CanAddContractingAction = false;
         CanSubmitContractingAction = false;
         IsDivisionPoc = false;
         IsDivisionManager = false;
         IsDivisionAdmin = false;
         IsAdmin = false;
         IsTTUser = false;
         IsTTUserForProjectEntry = false;
         IsTTUserForSummaryEntry = false;
         IsProjectEntryUser = false;
         IsABCAdmin = false;
         IsABCPOC = false;
         IsABCViewer = false;
         IsTech = false;
         IsContact = false;
         IsContributor = false;
         IsProd = false;
         IsIso = false;
         IsContractingOfficer = false;
      }
   }
}

 
 

I got UserPermissions under test. I used reflection, as seen below, to confirm that 23 getsetters existed and nothing more. There will be no way to fatten up this object without the test breaking and that might just be a good thing.

using System;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Whatever.Core.Tests
{
   [TestClass]
   public class UserPermissionsTests
   {
      public UserPermissionsTests()
      {
      }
      
      [TestMethod]
      public void permissions_are_all_false_by_default()
      {
         UserPermissions permissions = new UserPermissions();
         Assert.AreEqual(permissions.ActiveUser, false);
         Assert.AreEqual(permissions.ManagementReportViewer, false);
         Assert.AreEqual(permissions.CanSelectTimeEntry, false);
         Assert.AreEqual(permissions.CanSelectActivity, false);
         Assert.AreEqual(permissions.CanAddContractingAction, false);
         Assert.AreEqual(permissions.CanSubmitContractingAction, false);
         Assert.AreEqual(permissions.IsDivisionPoc, false);
         Assert.AreEqual(permissions.IsDivisionManager, false);
         Assert.AreEqual(permissions.IsDivisionAdmin, false);
         Assert.AreEqual(permissions.IsAdmin, false);
         Assert.AreEqual(permissions.IsTTUser, false);
         Assert.AreEqual(permissions.IsTTUserForProjectEntry, false);
         Assert.AreEqual(permissions.IsTTUserForSummaryEntry, false);
         Assert.AreEqual(permissions.IsProjectEntryUser, false);
         Assert.AreEqual(permissions.IsABCAdmin, false);
         Assert.AreEqual(permissions.IsABCPOC, false);
         Assert.AreEqual(permissions.IsABCViewer, false);
         Assert.AreEqual(permissions.IsTech, false);
         Assert.AreEqual(permissions.IsContact, false);
         Assert.AreEqual(permissions.IsContributor, false);
         Assert.AreEqual(permissions.IsProd, false);
         Assert.AreEqual(permissions.IsIso, false);
         Assert.AreEqual(permissions.IsContractingOfficer, false);
      }
      
      [TestMethod]
      public void UserPermissions_has_46_reflected_methods_for_23_getsetters()
      {
         Type type = typeof(UserPermissions);
         var methods = type.GetMethods();
         Assert.AreEqual(methods.Length, 50);
         MethodInfo info = methods[0];
         Assert.AreEqual(info.Name, "get_ActiveUser");
         info = methods[1];
         Assert.AreEqual(info.Name, "set_ActiveUser");
         info = methods[2];
         Assert.AreEqual(info.Name, "get_ManagementReportViewer");
         info = methods[3];
         Assert.AreEqual(info.Name, "set_ManagementReportViewer");
         info = methods[4];
         Assert.AreEqual(info.Name, "get_CanSelectTimeEntry");
         info = methods[5];
         Assert.AreEqual(info.Name, "set_CanSelectTimeEntry");
         info = methods[6];
         Assert.AreEqual(info.Name, "get_CanSelectActivity");
         info = methods[7];
         Assert.AreEqual(info.Name, "set_CanSelectActivity");
         info = methods[8];
         Assert.AreEqual(info.Name, "get_CanAddContractingAction");
         info = methods[9];
         Assert.AreEqual(info.Name, "set_CanAddContractingAction");
         info = methods[10];
         Assert.AreEqual(info.Name, "get_CanSubmitContractingAction");
         info = methods[11];
         Assert.AreEqual(info.Name, "set_CanSubmitContractingAction");
         info = methods[12];
         Assert.AreEqual(info.Name, "get_IsDivisionPoc");
         info = methods[13];
         Assert.AreEqual(info.Name, "set_IsDivisionPoc");
         info = methods[14];
         Assert.AreEqual(info.Name, "get_IsDivisionManager");
         info = methods[15];
         Assert.AreEqual(info.Name, "set_IsDivisionManager");
         info = methods[16];
         Assert.AreEqual(info.Name, "get_IsDivisionAdmin");
         info = methods[17];
         Assert.AreEqual(info.Name, "set_IsDivisionAdmin");
         info = methods[18];
         Assert.AreEqual(info.Name, "get_IsAdmin");
         info = methods[19];
         Assert.AreEqual(info.Name, "set_IsAdmin");
         info = methods[20];
         Assert.AreEqual(info.Name, "get_IsTTUser");
         info = methods[21];
         Assert.AreEqual(info.Name, "set_IsTTUser");
         info = methods[22];
         Assert.AreEqual(info.Name, "get_IsTTUserForProjectEntry");
         info = methods[23];
         Assert.AreEqual(info.Name, "set_IsTTUserForProjectEntry");
         info = methods[24];
         Assert.AreEqual(info.Name, "get_IsTTUserForSummaryEntry");
         info = methods[25];
         Assert.AreEqual(info.Name, "set_IsTTUserForSummaryEntry");
         info = methods[26];
         Assert.AreEqual(info.Name, "get_IsProjectEntryUser");
         info = methods[27];
         Assert.AreEqual(info.Name, "set_IsProjectEntryUser");
         info = methods[28];
         Assert.AreEqual(info.Name, "get_IsABCAdmin");
         info = methods[29];
         Assert.AreEqual(info.Name, "set_IsABCAdmin");
         info = methods[30];
         Assert.AreEqual(info.Name, "get_IsABCPOC");
         info = methods[31];
         Assert.AreEqual(info.Name, "set_IsABCPOC");
         info = methods[32];
         Assert.AreEqual(info.Name, "get_IsABCViewer");
         info = methods[33];
         Assert.AreEqual(info.Name, "set_IsABCViewer");
         info = methods[34];
         Assert.AreEqual(info.Name, "get_IsTech");
         info = methods[35];
         Assert.AreEqual(info.Name, "set_IsTech");
         info = methods[36];
         Assert.AreEqual(info.Name, "get_IsContact");
         info = methods[37];
         Assert.AreEqual(info.Name, "set_IsContact");
         info = methods[38];
         Assert.AreEqual(info.Name, "get_IsContributor");
         info = methods[39];
         Assert.AreEqual(info.Name, "set_IsContributor");
         info = methods[40];
         Assert.AreEqual(info.Name, "get_IsProd");
         info = methods[41];
         Assert.AreEqual(info.Name, "set_IsProd");
         info = methods[42];
         Assert.AreEqual(info.Name, "get_IsIso");
         info = methods[43];
         Assert.AreEqual(info.Name, "set_IsIso");
         info = methods[44];
         Assert.AreEqual(info.Name, "get_IsContractingOfficer");
         info = methods[45];
         Assert.AreEqual(info.Name, "set_IsContractingOfficer");
         info = methods[46];
         Assert.AreEqual(info.Name, "ToString");
         info = methods[47];
         Assert.AreEqual(info.Name, "Equals");
         info = methods[48];
         Assert.AreEqual(info.Name, "GetHashCode");
         info = methods[49];
         Assert.AreEqual(info.Name, "GetType");
      }
   }
}

 
 

Here is why I picked this to-do. The application generates a menu based upon a Web.sitemap file. A blob of C# (in a class a master page code behind inherits from) hid menu items based upon user permissions with some if/then logic. If one removed a line item from the XML in Web.sitemap one had to know to look to remove counterpart logic in the C# class. I did not know at first and I broke something. This seemed like a good thing to get under test in such a manner that one could not wreck the site by removing a menu item. My solution was to move the permissions logic into the XML, making line items now look like this:

<siteMapNode url="~/OpenProjectForm.aspx?d=1" title="New Ongoing Project" description="New Ongoing Project" criteria="IsAdmin|IsDivisionAdmin|IsDivisionManager" />

 
 

The criteria parameter is new. I wrote a static helper to loop through all of the nodes and return a blacklist of nodes a user should not see.

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
namespace Whatever.Core
{
   public static class DesignationsOfInaccessibleMenuItemsHelper
   {
      public static List<string> Retrieve(XmlDocument menu, UserPermissions keys)
      {
         List<string> blacklist = new List<string>() {};
         List<string> whitelist = new List<string>() {};
         IEnumerable<string> getters = GetListOfGetters();
         foreach(XmlNode tierI in menu)
         {
            blacklist = BuildBlacklist(tierI, blacklist);
            whitelist = Judge(tierI, whitelist, keys, getters);
            foreach (XmlNode tierII in tierI)
            {
               blacklist = BuildBlacklist(tierII, blacklist);
               whitelist = Judge(tierII, whitelist, keys, getters);
               foreach (XmlNode tierIII in tierII)
               {
                  blacklist = BuildBlacklist(tierIII, blacklist);
                  whitelist = Judge(tierIII, whitelist, keys, getters);
                  foreach (XmlNode tierIV in tierIII)
                  {
                     blacklist = BuildBlacklist(tierIV, blacklist);
                     whitelist = Judge(tierIV, whitelist, keys, getters);
                     foreach (XmlNode tierV in tierIV)
                     {
                        blacklist = BuildBlacklist(tierV, blacklist);
                        whitelist = Judge(tierV, whitelist, keys, getters);
                        foreach (XmlNode tierVI in tierV)
                        {
                           blacklist = BuildBlacklist(tierVI, blacklist);
                           whitelist = Judge(tierVI, whitelist, keys, getters);
                           foreach (XmlNode tierVII in tierVI)
                           {
                              blacklist = BuildBlacklist(tierVII, blacklist);
                              whitelist = Judge(tierVII, whitelist, keys, getters);
                              foreach (XmlNode tierVIII in tierVII)
                              {
                                 blacklist = BuildBlacklist(tierVIII, blacklist);
                                 whitelist = Judge(tierVIII, whitelist, keys, getters);
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
         foreach (string whiteitem in whitelist) blacklist.Remove(whiteitem);
         return blacklist;
      }
      
      private static List<string> Judge(XmlNode node, List<string> whitelist,
      UserPermissions keys, IEnumerable<string> getters)
      {
         Type type = typeof(UserPermissions);
         if (node.Attributes != null)
         {
            foreach(XmlAttribute attribute in node.Attributes)
            {
               if (attribute.Name == "criteria")
               {
                  string[] criteria = attribute.Value.Split('|');
                  string description = node.Attributes["description"].Value;
                  bool isUserAllowed = false;
                  foreach (string permission in criteria)
                  {
                     foreach (string getter in getters)
                     {
                        if (permission == getter)
                        {
                           MethodInfo info = type.GetMethod(Prefix() + getter);
                           if ((bool)info.Invoke(keys, null))
                           {
                              isUserAllowed = true;
                           }
                        }
                     }
                  }
                  if (isUserAllowed) whitelist.Add(description);
               }
            }
         }
         return whitelist;
      }
      
      private static List<string> BuildBlacklist(XmlNode node, List<string> blacklist)
      {
         Type type = typeof(UserPermissions);
         if (node.Attributes != null)
         {
            foreach (XmlAttribute attribute in node.Attributes)
            {
               if (attribute.Name == "criteria")
               {
                  string description = node.Attributes["description"].Value;
                  blacklist.Add(description);
               }
            }
         }
         return blacklist;
      }
      
      private static IEnumerable<string> GetListOfGetters()
      {
         List<string> getters = new List<string>() {};
         Type type = typeof(UserPermissions);
         var methods = type.GetMethods();
         foreach(MethodInfo info in methods)
         {
            if (info.Name.StartsWith(Prefix()))
            {
               getters.Add(info.Name.Replace(Prefix(), ""));
            }
         }
         return getters;
      }
      
      private static string Prefix()
      {
         return "get_";
      }
   }
}

 
 

I got the helper under test like so. This is cool code. It shows off manipulating the XmlDocument type.

using System.Xml;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace Whatever.Core.Tests
{
   [TestClass]
   public class DesignationsOfInaccessibleMenuItemsHelperTests
   {
      public DesignationsOfInaccessibleMenuItemsHelperTests()
      {
      }
      
      [TestMethod]
      public void happy_pass_returns_an_empty_list()
      {
         XmlDocument menu = new XmlDocument();
         UserPermissions keys = new UserPermissions();
         List<string> designations =
               DesignationsOfInaccessibleMenuItemsHelper.Retrieve(menu, keys);
         Assert.AreEqual(menu.InnerXml, "");
         Assert.AreEqual(designations.Count, 0);
      }
      
      [TestMethod]
      public void simple_example_for_returning_one_record()
      {
         XmlDocument menu = SiteMapFactory();
         UserPermissions keys = new UserPermissions();
         keys.IsAdmin = true;
         List<string> designations =
               DesignationsOfInaccessibleMenuItemsHelper.Retrieve(menu, keys);
         Assert.AreEqual(designations.Count, 5);
         Assert.AreEqual(designations[0], "IsABCAdminExample");
         Assert.AreEqual(designations[1], "IsDivisionManagerExample");
         Assert.AreEqual(designations[2], "ShouldAlwaysBeHidden");
         Assert.AreEqual(designations[3], "CanSelectTimeEntryExample");
         Assert.AreEqual(designations[4], "IsContributorExample");
      }
      
      [TestMethod]
      public void match_multiple_permissions()
      {
         XmlDocument menu = SiteMapFactory();
         UserPermissions keys = new UserPermissions();
         keys.IsContributor = true;
         keys.IsDivisionManager = true;
         keys.CanSelectTimeEntry = true;
         List<string> designations =
               DesignationsOfInaccessibleMenuItemsHelper.Retrieve(menu, keys);
         Assert.AreEqual(designations.Count, 3);
         Assert.AreEqual(designations[0], "IsAdminExample");
         Assert.AreEqual(designations[1], "IsABCAdminExample");
         Assert.AreEqual(designations[2], "ShouldAlwaysBeHidden");
      }
      
      [TestMethod]
      public void will_hide_everything_in_the_absence_of_permissions()
      {
         XmlDocument menu = SiteMapFactory();
         UserPermissions keys = new UserPermissions();
         List<string> designations =
               DesignationsOfInaccessibleMenuItemsHelper.Retrieve(menu, keys);
         Assert.AreEqual(designations.Count, 6);
         Assert.AreEqual(designations[0], "IsAdminExample");
         Assert.AreEqual(designations[1], "IsABCAdminExample");
         Assert.AreEqual(designations[2], "IsDivisionManagerExample");
         Assert.AreEqual(designations[3], "ShouldAlwaysBeHidden");
         Assert.AreEqual(designations[4], "CanSelectTimeEntryExample");
         Assert.AreEqual(designations[5], "IsContributorExample");
      }
      
      private XmlDocument SiteMapFactory()
      {
         string description = "description";
         string criteria = "criteria";
         
         XmlDocument menu = new XmlDocument();
         XmlElement tierI = (XmlElement)menu.AppendChild(menu.CreateElement("Node"));
         tierI.SetAttribute(description, "IsAdminExample");
         tierI.SetAttribute(criteria, "IsAdmin");
         
         XmlElement tierIIa = (XmlElement)tierI.AppendChild(menu.CreateElement("Node"));
         tierIIa.SetAttribute(description, "IsABCAdminExample");
         tierIIa.SetAttribute(criteria, "IsABCAdmin");
         
         XmlElement tierIIb = (XmlElement)tierI.AppendChild(menu.CreateElement("Node"));
         tierIIb.SetAttribute(description, "IsContributorExample");
         tierIIb.SetAttribute(criteria, "IsContributor");
         
         XmlElement tierIIIa =
               (XmlElement)tierIIa.AppendChild(menu.CreateElement("Node"));
         tierIIIa.SetAttribute(description, "IsDivisionManagerExample");
         tierIIIa.SetAttribute(criteria, "IsDivisionManager");
         
         XmlElement tierIIIb =
               (XmlElement)tierIIa.AppendChild(menu.CreateElement("Node"));
         tierIIIb.SetAttribute(description, "CanSelectTimeEntryExample");
         tierIIIb.SetAttribute(criteria, "CanSelectTimeEntry");
         
         XmlElement tierIVa =
               (XmlElement)tierIIIa.AppendChild(menu.CreateElement("Node"));
         tierIVa.SetAttribute(description, "ShouldAlwaysBeHidden");
         tierIVa.SetAttribute(criteria, "NeverMatchThis");
         
         XmlElement tierIVb =
               (XmlElement)tierIIIa.AppendChild(menu.CreateElement("Node"));
         tierIVb.SetAttribute(description, "ShouldNeverBeHidden");
         
         return menu;
      }
   }
}

 
 

There is a lot of my code that begs for further refactoring. I'm not crazy about the nested foreach statements in my helper. I had to do something comparable below in the name of using the generated list of unacceptable nodes to hide said nodes. I wonder if there was a way I could have "flattened" the XML hierarchy to beat this problem. What follows is the beginning of a method. You can see how I remove nodes from XML and use a double minus approach to walking a loop so that I never increment past something that was removed. (Honestly, the double minus stuff was already in the code base. I can't take credit.)

public void HideMenuItems(List<string> itemsToHide)
{
   for (int i = AppMenu.Items.Count - 1; i >= 0; i--)
   {
   MenuItem itemI = AppMenu.Items[i];
      string nameOfItemI = itemI.Text;
      if (itemsToHide.Contains(nameOfItemI))
      {
         AppMenu.Items.Remove(itemI);
      } else {
         for (int ii = AppMenu.Items[i].ChildItems.Count - 1; ii >= 0; ii--)
         {
            MenuItem itemII = AppMenu.Items[i].ChildItems[ii];
            string nameOfItemII = itemII.Text;
            if (itemsToHide.Contains(nameOfItemII))
            {
               AppMenu.Items[i].ChildItems.Remove(itemII);
            } else {
               for (int iii = AppMenu.Items[i].ChildItems[ii].ChildItems.Count - 1; iii >= 0; iii--)
               {

Lon Ingram on Treehouse at Austin JS

On Tuesday I saw Lon Ingram speak on Treehouse (at Austin JS) which is a JavaScript project that attempts to allow one to run external JavaScript libraries safely. Many external JavaScript libraries which run at URLs a user doesn't control which seem innocuous may in fact be sinister and place a 1 by 1 .gif image at your site with sensitive data collected from your local environment in get variables in the path to image. The analytics back at the site hosting the tiny image record the get variables and, voilà, another party has your information. Treehouse tries to find this sort of manipulation. Mr. Ingram did admit that it has its shortcomings however.

at AustinJS on Twitpic

 
 

Things Austin JS peeps talk about that I found interesting:

  1. A Web Worker offers a way to run a .js script in a sandbox independent of a browser thread. Chrome and IE10 support debugging Web Workers. Web Workers run significantly slower than regular browser threads.
  2. DOM Nodes (In the DOM, everything in an HTML document is a node.)
  3. XHRs
  4. FRAG tags - The idea behind this “document fragment” tag is that it be used to wrap 3rd party content – ads, widgets, and analytics.
  5. SpiderMonkey (Mozilla's JavaScript engine)

Unicode Converter

Type odd characters you find online in at http://www.rishida.net/tools/conversion/ and look to the "Hexadecimal NCRs" value for the HTML encoding for the character.

Friday, May 18, 2012

make a Report Server Project in BIDS

In making a new project in BIDS (SQL Server Business Intelligence Development Studio), I selected "Report Server Project."

attempting to make a new project in BIDS on Twitpic

This makes a project that appears to have two folders in the Solution Explorer:

  1. Shared Data Sources (.rds files)
  2. Reports (.rdl files)

 
 

All content really just kept in one folder. The fake folders just help divide up files.

Thursday, May 17, 2012

rsInvalidDataSourceReference

An error like this when viewing an SSRS report...

The report server cannot process the report or shared dataset. The shared data source 'YOURNAMEHERE' for the report server or SharePoint site is not valid. Browse to the server or site and select a shared data source. (rsInvalidDataSourceReference)

 
 

...may occur when specifying "Credentials stored securely in the report server" as the "Connect using" option at a datasource, and even so when one gets "Connection created successfully" upon clicking the "Test Connection" button. How is this possible? If you navigate to the Security tab for the data source you will likely see that the user you specified is just not there in the list of permissioned users. Click "New Role Assignment" to add the user. Give the user the "Browser" role.

multi-factor authentication

  • SSO stands for Single Sign On
  • IAM stands for Identity and Access Management
  • Multi-factor authentication involves verifying one is one's self by more that one of three means:
    1. Something the user knows such as a username, an email address, or a password
    2. Something the user has such as a hardware token, a virtual token, a smart card or USB dongle
    3. Something the user is such as a thumbprint scanner or an iris scanner

DevExpress grid will paginate on the server….

so says Luis Blanco

Monday, May 14, 2012

Lucene.NET

overview of Lucene.NET on Twitpic

I saw Chander Dhall of Ria Consulting speak at the Austin.NET User's Group tonight. He spoke on Lucene.NET (which is a port of Lucene for Java). I learned:

  1. SOLR and something called Elastic Search (which scales better) both run on top of Lucene which itself runs in Apache. Lucene.NET offers a .dll. Perhaps the .dll lets you interface with the Apache-running stuff from the C# side??? I don't know.
  2. Lucene may store stuff in raw RAM in lieu of merely databases or flat files making it really fast.
  3. The configuration for searches is very capable. Phrase Queries allow one to match terms that are "close" to a term suggested in a search. Fuzzy Queries match phonetically!
  4. .cfx extension files are index files, made from crawling content.
  5. The auto suggest feature at a search field could be driven from crawling existing .cfx files and creating auto suggest-specific indexes. Some of Chander's code here offers an IndexWriter.
    some of Chander's code... he is making an index of a par... on Twitpic
    Chander suggested that one may game auto suggest to make the product you really want to sell appear first in a search of products. There is a door open for this sort of manipulation with Lucene.
  6. Searches crawl indexes and thus it is not wise to search against common words like "and" or "the."
    "the" and "and" are killers!!! on Twitpic
    Luckily, Lucene will compensate for this problem for you if you'll let it.
  7. Don't put sensitive data like the cost of a product to your company in Lucene. Anything that needs to be hidden by security is something that Lucene shouldn't be concerned with to begin with. You can secure this sort of stuff in Lucene, but it will just make searches slower.
  8. Tika is for rich text extraction.
  9. Eric Hatcher is someone to find on YouTube for how-to stuff on Lucene.

RavenDB is not truly NOSQL as it supports asynchronous transactions.

So says Chander Dhall!

Saturday, May 12, 2012

DateTimeOffset

A DateTimeOffset is somewhat akin to a DateTime which carries with it a TimeSpan which denotes the offset from Coordinated Universal Time (UTC) time (which in casual use is the same thing as Greenwich Mean Time). Cool stuff. Chapter 5 of "C# 4.0 in a Nutshell" touches on DateTimeOffset and has a bunch of other DateTime-related notes.

DateTime cheat sheet from the bottom of page 211 of "C# ... on Twitpic

Thursday, May 10, 2012

the manner in which getsetters reflect

I made a class which only had 20 getsetters and nothing else beyond a constructor. Then I used this means to determine the methods by way of reflection. type.GetMethods() gave me 44 methods! Four of them were:

  1. ToString
  2. Equals
  3. GetHashCode
  4. GetType

 
 

Remaining were the forty methods for twenty getsetters. Each getsetter had two methods upon reflection. A getsetter for Foo would be reflected like so:

  1. get_Foo
  2. set_Foo

 
 

The manner in which getsetters reflect is another thing I picked up from C# 4.0 in a Nutshell!

Web.sitemap custom attributes

This explains that one may doctor custom attributes into Web.sitemap like so:

<siteMapNode url="~/Default.aspx" title="Home" description="Home" foo="bar" />

 
 

...and then fish them back out like so in C#:

if (SiteMap.Current["foo"] == "bar") {

MEF

This suggests: The Managed Extensibility Framework (MEF) is a composition layer for .NET that improves the flexibility, maintainability and testability of large applications. MEF can be used for third-party plugin extensibility, or it can bring the benefits of a loosely-coupled plugin-like architecture to regular applications.

Wednesday, May 9, 2012

How to export a SharePoint 2010 list to Excel

  1. navigate to the list in question
  2. click on the "List" tab within the "List Tools" tab
  3. click Export to Excel
  4. You will end up with a .iqy file which one may open in Excel just by double-clicking upon it. This format references the live data in the SharePoint list and gives it to you in Excel format.
  5. save out a .xlsx file from the .iqy file

Tuesday, May 8, 2012

uninstall a Visual Studio template

at: Tools > Extension Manager...

Open Folder in Windows Explorer

In Visual Studio 2010, right-click on a project and select "Open Folder in Windows Explorer" to open up a Window Explorer folder with the contents of the project. Duh.

Monday, May 7, 2012

User Interface Technologies

Page 187 of C# 4.0 in a Nutshell suggests there are four user interface technologies:

  1. ASP.NET (that which shall ultimately become HTML)
  2. Silverlight
  3. WPF (Windows Presentation Foundation)
  4. Windows Forms

 
 

The applicable bit of page 187 is shown here:

WINDOWS FORMS: for maintaining LEGACY rich client applications on Twitpic

AsyncRendering

http://msdn.microsoft.com/en-us/library/microsoft.reporting.webforms.reportviewer.asyncrendering.aspx is the magic for letting SSRS drillthroughs work in ReportViewer web forms controls. Add this to the ReportViewer tag:

AsyncRendering="False"

A drillthrough in an SSRS report is a link to another SSRS report.

<ActionInfo>
   <Actions>
      <Action>
         <Drillthrough>
            <ReportName>FooSummary</ReportName>
            <Parameters>
               <Parameter Name="FooId">
                  <Value>=Fields!fooID.Value</Value>
               </Parameter>
            </Parameters>
         </Drillthrough>
      </Action>
   </Actions>
</ActionInfo>

Why can't I create a database locally?

When facing this error...

CREATE DATABASE permission denied in database 'master'

 
 

...try right-clicking on the SQL Server Management Studio icon and then selecting "Run as administrator" to be able to create a user account for yourself that has the needed permissions. This should let you edit databases created as administrator.

Windows XP Virtual Machine for Windows 7

http://www.microsoft.com/windows/virtual-pc/download.aspx

long polling example

http://stackoverflow.com/questions/333664/simple-long-polling-example-code has a long polling example although I do not care to think about it right now. It looks like one just makes an .ajax jQuery call and uses the timeout, error, and cache (cache: false) settings. I don't know if this works or not.

long polling on Twitpic

Saturday, May 5, 2012

interesting way to see if images have been loaded

Per this, get the heights and widths of images with jQuery like so:

var x = $("#photoA").height();
var y = $("#photoB").width();

 
 

...then check to see if a value is over, um, say 40 pixels or so...

Friday, May 4, 2012

Right-click on "Computer" in the Start Menu in Windows 7 and then select Properties to learn...

  1. computer name
  2. variety of Windows 7
  3. 64 or 32 bit
  4. RAM and CPU specs

Where are the SharePoint .dlls?

This thread suggests that in order to lay hands on the Microsoft.SharePoint .dlls for Microsoft.SharePoint, Microsoft.SharePoint.Linq, and MicrosoftSharePoint.Security dependencies, one must pull the .dlls from their install of SharePoint server from here:

C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI

Is .udl the Web.config of a VB6 app?

It looks like I'm gonna find out. :|

Thursday, May 3, 2012

A class and an interface that really need each other!

Here is some more magic from "C# 4.0 in a Nutshell."

namespace Whatever
{
   public interface IFoo
   {
      string SaySomething();
   }
}

 
 

There is no way to call the SaySomething method without casting an instance of Foo to an instance of IFoo.

namespace Whatever
{
   public class Foo : IFoo
   {
      string IFoo.SaySomething()
      {
         return "I can talk!";
      }
   }
}

 
 

This test passes.

[TestMethod]
public void TestMethod()
{
   Foo foo = new Foo();
   IFoo ifoo = (IFoo) foo;
   Assert.AreEqual(ifoo.SaySomething(), "I can talk!");
}

SDK

...stands for software development kit. Devkit is synonymous.

SIG

...stands for Special Interest Group

What projects may I "see" in TFS?

One may right-click on the collection at the top of the Team Explorer pane and select "Connect to Team Project..." to see a list of what Team Foundation Server projects are selected to be seen in the Team Explorer pane. One may check and uncheck projects here. One should be able to see all potential projects in the Solution Explorer also.

Wednesday, May 2, 2012

POST and GET variables in web forms

In web forms Request.QueryString["foo"]; will pull something out of the URL line and Request.Form["bar"]; will grab ahold of a POST variable.

triage

triage - the determination of priorities for action in an emergency

templates

By going to File > Export Template... in VS2010 one may export a template. One must then install the template to use it. The Projects and Solutions Templates are kept at a path specified in the General subsection beneath the "Projects and Solutions" section in Options... found under the Tools menu. Mine were at C:\Users\vafscjaesct\Documents\Visual Studio 2010\Templates\ProjectTemplates for example. I don't understand how to do an install as of this writing/moment.

httpHandlers versus handlers

In Web.config: httpHandlers in system.web is of IIS6 while handlers in system.webServer is of IIS7. http://world.episerver.com/Documentation/Items/Tech-Notes/EPiServer-CMS-5/EPiServer-CMS-5-R2/Changes-Between-IIS6-and-IIS7/ touches on as much.

In system.web one may need to add assembly references likes so:

<assemblies>
   <add assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0,
         Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
   <add assembly="Microsoft.ReportViewer.Common, Version=10.0.0.0,
         Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
   <add assembly="Microsoft.Build.Framework, Version=4.0.0.0,
         Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A" />
</assemblies>

The GAC is .NET Global Assembly Cache.

If something seems to be running without the needed external dependency in the bin folder, perhaps their is a .dll in the GAC which is filling in the gap. Get at the GAC in Windows 7 by typing run at the start menu and then enter C:\Windows\Assembly\gac

draw SSRS into web forms

So far I have only encountered web forms implementations of SRSS incorporations in apps. A web form will sort of make an iframe out to SSRS content with a ReportViewer control like so:

<rsweb:ReportViewer ID="ReportViewer1" runat="server" Font-Names="Verdana"
   Font-Size="8pt" InteractiveDeviceInfos="(Collection)" ProcessingMode="Remote"
   WaitMessageFont-Names="Verdana" WaitMessageFont-Size="14pt" Width="920px"
   Height="500px">
</rsweb:ReportViewer>

 
 

You will need to have references to Microsoft.ReportViewer.Common and Microsoft.ReportViewer.WebForms and you will need a ScriptManager in the same web form as the ReportViewer control. Also, you may only have one ReportViewer on a web form at a time.

<asp:ScriptManager runat="server"></asp:ScriptManager>