Friday, June 28, 2013

Getting Started With Dapper Part 2

This video is part 2 of a very basic introduction to the micro ORM Dapper for use with the .Net platform.  I go over IEnumerable and how it relates to Dapper, as well as demonstrating several different classes that implement IEnumerable (Lists, Arrays, Dictionaries).

I also go over what happens with .First and .FirstOrDefault when used with Dapper/IEnumerable and how the behavior can be different for value types vs. reference types.




The source code for this project can be found here: 

You can find more info about Dapper here: code.google.com/p/dapper-dot-net/.

Tuesday, June 25, 2013

An apology to Jon Skeet

Mr. Skeet doesn't know me and no one that knows me has ever heard me say anything negative about him, so it may seem odd that I'm writing this apology.

But sometimes, when no one is around, and I'm watching a video from tekpub (like one of these), I find myself drumming my fingers and eventually I yell something like this:

"GET TO THE POINT!  I don't care about every last little nuance of the CLR!  Who cares if Ildasm looks different for this or that, just tell me about Lambdas!  Great Caesar's Ghost!  Just stop it already, quit bringing up Noda-Time and get to point!".

Well, I'm trying to make some screen casts of my own and in addition to trying to get the sound to...sound right, I'm realizing that many times you have to go deep into the details or you aren't explaining things properly.

Take my first stab, Getting Started With Dapper.  Dapper has been out for a while (most howto posts regarding Dapper are from 2011) so I thought it would be fairly easy to do a screen cast on it.  I've used it a lot.  I know my way around it.  Piece of cake, right?

Everything was going fine until I realized that I didn't really explain why I put a ToList() on the end of my Dapper.Query<T> calls.  The reason, of course, is that I like working with generic lists and .Query<T> returns IEnumerable<T>.  So I throw on a .ToList() to get things like I want them.  But that brings up the question, why does Dapper do that?  If I don't explain why IEnumerable is used instead of other collection types, then I'm really doing a screen cast on how I use Dapper rather than what Dapper does.

So I started writing text for an aside on IEnumerable.  I quickly realized this needed to be it's own separate screen cast because when you hit the period after typing .Query<T>("") there are a kah-jillion other Linq extension methods that pop up:

I didn't go crazy and spend time on each one, but there are several that need to be discussed.  And they behave differently with value types vs. references types and reference types behave differently than nullable reference types and...sheesh. I just wanted to make a screen cast about Dapper and expand the brand a little bit and now I'm looking through the C# specifications!

I'm taking my time and hopefully making good choices about what needs to be discussed and what can be left out.  But, there's more to it than I originally thought.

And while I can't claim to have walked a mile in Jon Skeet's shoes (his SO score is 576,875 while mine is...6), I can say that I've walked, maybe an metaphorical inch in his shoes.  After travelling even such a short distance as this, I feel compelled to say to Mr. Skeet, "I'm sorry I yelled at your tekpub video late at night when no one could hear me.  I just didn't know."

Just before I scheduled this post, I went to Mr. Skeet's twitter page and saw this exchange:

Pretty good advice.

Friday, June 21, 2013

My First Screen Cast - Getting Started with Dapper Pt1.

So I decided to try my hand at screen casting.  This is my first effort and I found, as many others have before me, it's not easy getting a screen cast to look anything close to decent. But practice makes...something less bad than before.  Anyway, enough with the self depreciation.

This screen cast is a very basic introduction to the Mirco ORM Dapper.  This and the next several screen casts will be targeted towards what I refer to as "default developers".  Default developers are developers (like myself a few years ago) who primarily take what Microsoft gives them.  If it's not "in the box" or on MSDN, then it's not on the radar.  It is not my intention to demean the default developer.  Like I said, I used to be one.  My intention is to make the material covered as approachable as possible crack open the door to all the great non-Microsoft things that are being done with .Net.

So check out my Dapper video.  If you have any suggestions for improvements or think I got something flat out wrong, please let me know in the comments or send an email.



Intro To Dapper - Part 1 from Jon Wear on Vimeo.

Source code can be found here: https://github.com/genghisjahn/DapperIntroPt1/archive/Pt1.zip

Thursday, January 3, 2013

A Case for the Interface

"I don't get interfaces.  If I need a method in a class I'll put the method in the class.  Why waste time putting the method definition in another file and then write the code I was going to anyway in the class definition?"

I may or may not have said something like this at some point in my software career.  I have certainly heard the usefulness of interfaces questioned over the years.  The questioners are almost always self taught developers, such as myself who have managed to write gobs of decent applications without ever seeing the need for an interface.  The fact that the .Net framework is littered with them ought to be a clue that somebody who was smart enough to build the .Net framework thought they were useful.

But we're not building a new framework, are we?  We're building text over data apps, right?  Who needs 'em?

We all do.  In the words of Fire Marshall Bill, "Let me show you something."

It's my first day on the job/project/team and I've been given a task.  The task is simple:

Build a method that takes in a last name and first name argument and returns a list of customers that start with the name arguments.

Easy!

I write a stored procedure, then I add a Linq To SQL designer, drag the stored procedure onto it and I'm done in four lines of code:



static List<GetCustomersResult> GetCustomers(string lastname,string firstname)
        {
            List<GetCustomersResult> result = new List<GetCustomersResult>();
            lqDataContext lq = new lqDataContext();
            result = lq.GetCustomers(lastname, firstname).ToList();
            return result;
        }

I'm all happy until the person who tells me what to do comes by and looks at it and says, "Oh, well that will work for this department, but if I want to search for new customers, they are in a flat file.  They are there for a week or so until they get processed into the main customer database.  And we also have separate customer databases from companies we bought back in the 90s.  One is in Access, another is in Fire Fox."

"You mean Fox Pro?" I ask.

"Fox Pro, yeah.  Fire Fox is the Internet Explorer, I forgot.  Anyway there are those and maybe some others I'm forgetting about."

I smile, nod and turn back to my four lines of code.  This isn't going to cut it.

Quick Aside: The above exchange was the obligatory "All Managers R Stupid" joke.  Your manager most likely is not stupid, they most likely have a whole host of problems that would keep you up screaming at night.  In fact, it probably keeps them up screaming at night.

So in almost no time at all, this project has grown from one data source to at least three.  As additional meetings happen, there could very well be more.  If I've done my job well, it's entirely possible that other departments will hear about it and want to add their subset of customer records to this process.  There's no telling how many data sources this will ultimately use.  All of them will could have different connection info.

Here's where I can use an interface to make things easier.  Now, if you keep scrolling it may look like this is more complicated, but I'm saving myself a lot of future trouble.  This particular boss has already proven to be a slow roller with the requirements, so an ounce of prevention...

First, I create an interface with one required method:

public interface ICustomerGetter
    {
        List<Customer> GetCustomers(string lastname, string firstname);
    }

Quick Aside: All an interface does is list methods that a class has to have if it's going to implement the interface.  It doesn't contain any of the innards, just how methods must be called and what will be returned.

Second, I create a simple POCO to hold the customer info:


public class Customer
    {
        public Customer() { }
        public Customer(int customerID, string lastname, string firstname, DateTime createdon)
        {
            this.customerID = customerID;
            this.lastname = lastname;
            this.firstntame = firstname;
            this.createdon = createdon;
        }
        public int customerID { get; set; }
        public string lastname { get; set; }
        public string firstntame { get; set; }
        public DateTime createdon { get; set; }
    }

Third I create a SQLGetter Class. It implements the ICustomerGetter interface, and has some extra stuff in it to keep track of query strings and linq to sql type stuff. Since it implements the ICustomerGetter interface, it has to have a method called GetCustomers that takes a string lastname and firstname parameters and returns a typed list of customers. The interface says I have to have it, how I must call it and what it must return. What goes on in the middle is up to me.

public class SQLGetter : ICustomerGetter
    {
        string cn = "";
        public SQLGetter(string ConnectionString)
        {
            cn = ConnectionString;
        }
        public List<Customer> GetCustomers(string lastname, string firstname)
        {
            List<Customer> result = new List<Customer>();
            lqDataContext lq = new lqDataContext(cn);
            lq.Open();
            var dbcurrentcustomers = lq.GetCustomers(lastname, firstname).ToList();
            foreach (var i in dbcurrentcustomers)
            {
                result.Add(new Customer(i.customerID, i.lastname, i.firstname, i.createdon));
            }
            lq.Close();
/* You could remove the above foreach loop and use the following Lamba expression. * It accomplishes the same thing. * * result = dbcurrentcustomers.ConvertAll(i => new Customer(i.customerID, i.lastname, i.firstname, i.createdon)); * */ return result; } }
Fourth, I build my flat text file getter.  I create a new class called FileGetter that implements ICustomerGetter.  This class takes a string path argument when it's instantiated, it implements the GetCustomers method as required and looks through a text file to find matching records.  It looks like this:


public class FileGetter:ICustomerGetter
    {
        private string path;
        public FileGetter(string path)
        {
            this.path = path;
        }
        public List<Customer> GetCustomers(string lastname, string firstname)
        {
            List<Customer> result = new List<Customer>();
            var customers = System.IO.File.ReadAllLines(path);
            foreach (string c in customers)
            {
                string[] custdata = c.Split(',');
                Customer customeritem = new Customer(Convert.ToInt32(custdata[0]), custdata[1], custdata[2], new DateTime());
                if (customeritem.lastname.StartsWith(lastname) && customeritem.firstntame.StartsWith(firstname))
                {
                    result.Add(customeritem);
                }
            }
            return result;
        }
    }

Fifth, I create a method that does the main search.  It looks something like this:


static List<Customer> GetMainCustomers(List<ICustomerGetter> getters, string lastname,string firstname)
        {
            List<Customer> result = new List<Customer>();
            foreach (var g in getters)
            {
                result.AddRange(g.GetCustomers(lastname, firstname));
            }

            /* Below is another lamba expression.  Nothing scary here.
             * It's just returning the result list so that the items are ordered by lastname,firstname.
             * */
            return result.OrderBy(ln => ln.lastname).ThenBy(fn => fn.firstntame).ToList();
        }


This GetMainCustomers method takes three arguments, a list of objects that implement ICustomerGetter, a string for lastname and for firstname.  The cool thing about the first argument is that the getter objects don't have to be the same type.  All they have to do is properly implement the ICustomerGetter interface.  They could have different properties, and all sorts of things but as long as they implement everything in the interface, our GetMainCustomers method is happy.

Now, we loop through each ICustomerGetter object, do the search and return the results.

Lastly, the calling method would look like this:


static void Main(string[] args)
        {
            string cn = Properties.Settings.Default.customerdataConnectionString.ToString();
            SQLGetter sqlgetter = new SQLGetter(cn);
            FileGetter fgetter = new FileGetter(@"c:\temp\customers.txt");

            List<ICustomerGetter> getters = new List<ICustomerGetter>();
            getters.Add(sqlgetter);
            getters.Add(fgetter);

            List<Customer> customers = GetMainCustomers(getters,"B", "D");
        }

Now that we've done all this work, what does it give us?

Well, now we can add new customer getters for Access and FoxPro just by making sure they properly implement the ICustomerGetter interface.  We can create multiple instances of each object if there happen to be more than one source file for Access or the text file.

We can also decide to call the method with just one getter if we only wanted new customers from the text file getter, or if we only wanted current customers from the SQL getter.

We can also easily test this code by building hard coded values to see what would happen under certain circumstances.  Let's say one of the text files doesn't have an ID in the first position, or maybe we want to add rules to make sure that the customerID field is always unique, we could make tests that force the method to deal with items with non-unique IDs.

So there you go, that's why you might want to use an interface.  It helps you plan for the unknown.

Tuesday, February 21, 2012

Trouble with the jQuery-tmpl plugin

I used the jquery-tmpl plugin extensively on the Docphin website.  It is a great tool and allowed me to do some  things without all the normal asp.net web form bloat.  However, there was one small (make that large) problem.  The site didn't work from inside any VA hospital.  Well, the site worked but the parts of the site that relied on the jquery tmpl plugin didn't work and it just so happened that most of the content of the site relied on it.  No good.

It was baffling.  The site worked fine across all browsers but at two different VA hospitals, the site would fail when it tried to apply the jquery template to the returned data context.  I could see through firebug that the data had returned and that it was correct, but when it hit the .appendTo method I would get:

Object doesn’t support this property or method

Drove me crazy.  I setup a demo page that did a very simple call to the plugin, but that didn't work either.  I tried updating my jQuery include thinking that maybe there was something about an older version that didn't work well.  I'd read on Boris Moore's blog (he's the author of the plugin) that tmpl was being depreciated and that JsView and JsRender were taking over.  I wrote demo pages for those newer plugins as well.  They all worked fine except at the VA.  They all returned the same error those locations.

I tried a few other things but I decided to work on something else and come back to the problem later.  One of those other things was to give the docphin website an SSL certificate.  I installed it and made sure everything on the pages were calling outside resources through SSL so that I wouldn't get those annoying "not everything on the page is encrypted" notifications.  Once that was set, I had someone test the site again from the VA hospital, just to see if SSL made any difference.  It did.  No more problems. The tmpl worked fine.

So my guess is that the network security rules at the VA hospitals prevents non encrypted ajax calls that make use of non standard script types(in this case the type="text/x-jquery-tmpl).  That's a mouthful, but that appears to be it.  I haven't tried it with JsView and JsRender yet, but I assume it will work.

So, if you are using the jQuery tmpl plugin on a website and it keeps failing on the .appendTo() method at a specific location but it works everywhere else, try making the site SSL.  It works if you are at the VA.

Monday, July 4, 2011

jQuery tmpl page size vs. asp.net server control page size.

My previous post went over how to do a simple data bind using client side data binding with the jQuery tmpl plugin as opposed to data source objects and grid server controls that are often used with asp.net.  I think it's better way to go when possible.  One of the benefits of the tmpl plugin is that the page size is much smaller and you get to do away with all that view state.

I created a new project that does the same thing as the project from my previous post, only it uses asp.net UI server controls as well as the script manager and update panel controls.  You can download the new project here.

Figures 1,2 and 3 are screen shots of  web page properties from the new project along with a description of what you are looking at.  The main thing we care about is page size.


Figure 1

Have a look at figure 1.  This is just a plain asp.net page that has no ajax on it.  Just regular post backs.  Notice the page size is 4,766 bytes.















Figure 2

In figure 2 the same project, but we added a script manager tag which is required for a .net page that's going to use the ajax control tool kit or any of the ajax controls like the update panel.  Notice the size has jumped to 6,433 bytes and we haven't even added any update panels yet.













Figure 3

Here in figure three we have added the update panel, so that now our application mimics the jQuery application from the previous post.  Notice the size of the page is now 6,562 bytes.















Figure 4

Now in figure 4 I'm running the jQuery tmpl demo application from the previous post.  Notice the page size is 2,037 bytes.  That's less than 1/3 the size of the server control version using the script manager and the update panel.  No big deal you say?  In the world if 3G, it is a big deal.  On a network with lots of traffic, it is a big deal.   I think it's a more elegant solution.












Note: The property pages are from Internet Explorer 8, but the type is Chrome HTML Document because Chrome is my default browser.

Saturday, July 2, 2011

jQuery tmpl plugin example for ASP.Net

Originally I was going to call this post, "Look Ma!  No view state!" but view state isn't really what I to talk about it.  This example will have no view state, but that's a side benefit.

What I want to talk about is client side data binding with jQuery.  The jQuery tmpl plugin has been documented in a number of places and I'm not going to show anything new here.  This post is intended to be a simple example for people still using data grids and heavy .Net server controls.  This example won't use any server controls.  We won't have a form tag and there will be no code behind.  Let's get to it.

Step 1: Create a web service

Here's our simple web service.  I called it "wsPlayers".  It has one method and returns a list of custom objects based on a simple NBAPlayer class.  Be sure to uncomment the line...

[System.Web.Script.Services.ScriptService]


...so that the web methods in the service can be called from client side JavaScript. We will also want to add a reference to the Script.Services namespace at the top of the file...

using System.Web.Script.Services;

...so that we can change the format of our web method to JSON (it's XML by default).

So here is the full  text of our web service method:


Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services; //Have to add this namespace for the ResponseFormat on the webmethod).
   
namespace tmplDemo
{
 /// <summary>
 /// Summary description for wsPlayers
 /// </summary>
 [WebService(Namespace = "http://tmplDemo/")]
 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
 [System.ComponentModel.ToolboxItem(false)]
 // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
 [System.Web.Script.Services.ScriptService]
 public class wsContacts : System.Web.Services.WebService
 {

  [WebMethod]
  //***The ResponseFormat has to be added to the method, not the WebService Class (above).
  [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
  public List<NBAPlayer> GetPlayers(int paramMinChampionships)
  {
   List<NBAPlayer> tempPlayers=new List<NBAPlayer>();
   
   NBAPlayer temp1 = new NBAPlayer("Nowitzki","Dirk",1);
   NBAPlayer temp2 = new NBAPlayer("James", "LeBron", 0);
   NBAPlayer temp3 = new NBAPlayer("Wade", "Dywane", 1);
   NBAPlayer temp4 = new NBAPlayer("Bryant", "Kobe", 5);
   NBAPlayer temp5 = new NBAPlayer("Paul", "Chris", 0);
   
   tempPlayers.Add(temp1);
   tempPlayers.Add(temp2);
   tempPlayers.Add(temp3);
   tempPlayers.Add(temp4);
   tempPlayers.Add(temp5);

   return (from p in tempPlayers 
     where p.championships>=paramMinChampionships 
     orderby p.lastname,p.firstname
     select p).ToList<NBAPlayer>();
  }
 }
 public class NBAPlayer{
   public NBAPlayer(string lname,string fname,int chmps){
   lastname=lname;
   firstname=fname;
   championships=chmps;
  }

  public NBAPlayer()
  {

  }

  public string lastname { get; set; }
  public string firstname { get; set; }
  public int championships { get; set; }
 }
}

As you can see from the code, the web service has a method called GetPlayers and it accepts one parameter of type int called paramMinChampionships.  It then returns a list of type NBAPlayer where each NBAPlayer object has a championship property equal to or greater than the paramMinChampionships.

Now, I've made a custom class and hard coded a few elements for the example but this is where you'd put your database calls or Linq objects and build your return set that way.  We're done with the web service.

Step 2: Download jQuery files.


Create a directory in your project called jQuery.  Download these two jQuery files:


Add these files to the jQuery directory you made at the beginning of this step.

Step 3: Create a default.aspx page.




Add a new file called default.aspx.  Once you've done that, your solution explorer should look something like the image at left.







Now the fun part.  First we're going to create some javascript that will do our Ajax call for us:

<script type="text/javascript">
        function GetPlayers() {
            $.ajax({
                url: "wsPlayers.asmx/GetPlayers",
                dataType: "json",
                type: "POST",
                contentType: "application/json; charset=utf-8",
                data: ("{paramMinChampionships: " + $("#selChamps").val() + "}"),
                error: function (err) {
                    alert("Error:" + err.responseText);
                },
                success: function (results) { OnComplete(results.d) }

            });
        }

        function OnComplete(results) {
            $("#tbodyPlayers").empty();  //We want to clear the body of the table first.
            $("#playerDataTemplate").tmpl(results).appendTo("#tbodyPlayers");
        }

    </script>


If that doesn't make sense, then stop right here and read about the jQuery Ajax method.  What we're doing is calling our web service and passing it a numeric value so that it will give us back our list of players.  Before we do that lets add the rest of the HTML to our default.aspx page.

We want a select element that looks like this:

Players with at least 
    <select id="selChamps"> 
        <option value="0">0</option> 
        <option value="1">1</option> 
        <option value="2">2</option> 
        <option value="3">3</option> 
    </select> 
    championships.

We'll want a button to fire off our ajax web service call:

<button id="btnSubmit" onclick="GetPlayers();" >Submit</button>

We'll also want a table to display our data:

<table border="1"> 
        <thead> 
            <tr> 
                <td>First Name</td> 
                <td>Last Name</td> 
                <td>Championships</td> 
                <td>Bing</td> 
            </tr> 
        </thead> 
        <tbody id="tbodyPlayers"> 
         
        </tbody> 
    </table>

Lastly, and most importantly, we add the data template:

<script id="playerDataTemplate" type="text/x-jquery-tmpl"> 
    <tr> 
        <td>${firstname}</td> 
        <td>${lastname}</td> 
        {{if championships>0}} 
        <td align="center"><span style="color:green;font-weight:bold;">${championships}</span></td> 
        {{else}} 
        <td align="center">${championships}</td> 
        {{/if}} 
        <td><a target="_blank" href="http://www.bing.com/search?q=${firstname}+${lastname}">search</a></td> 
    </tr> 
</script>


That's right, we're putting HTML markup directly inside our <script> tag in the example above.  Notice that the type is type="text/x-jquery-tmpl" and not type="text/javascript". This is a different kind of script that works with the tmpl plugin. The magic is in the OnComplete method and the data template we created.  Pay special attention to this line of JavaScript code:

$("#playerDataTemplate").tmpl(results).appendTo("#tbodyPlayers");

What this means is, we're going to take the value of results, which is the JSON object that contains our list of player data, pass it to the tmpl function of the playerDataTemplate selector and append the output to the
tbodyPlayers selector. The playerDataTemplate will apply what's inside for each element in the results variable. As you can see, by using the {} brackets we can drop the values of the properties whereever we want.  We can apply conditional if/else and we can put our property values inside HTML markup. And we can do it all without asp.net server controls or a code behind.  Well,we do have a code behind of sorts but that is encapsulated in the web service.  So if we have an iPhone app that wants to call our web service, no problem.  Windows forms wants to use it?  No problem.  Another thing about this approach is that we are getting away from all the custom .net control styling markup and back to straight up css.  Now when a designer looks at our source and wants to make some tweaks, they don't see a buch of <asp:textbox id="txtFirstName" runat="server" text="Johnny" />.  The see regular HTML that they should be able to update without breaking anything.

Another advantage to this approach is that we are doing an Ajax call but since we're not using an asp.net update panel and things like that, we're only sending and receiving the JSON objects.  That's a really light payload compared to all the view state stuff we'd get if we used update panels.  We also aren't using an asp.net script manager, we're just referencing our jQuery libraries normally so we don't have that overhead either.  I may do a follow up post to this one where I use update panels, script managers and a datagrid to show the difference in page size and network traffic.  It makes a huge difference.

So, that's the tmpl plugin for jQuery and that's why I love it.  If you want to play around with this project yourself, you can download the whole thing here.