2013 TRINUG Code Camp

All of my materials for my presentations can be found here.

Here are a couple of pictures from code camp.  The Eject-A-Bed presentation:

image

And the F# One:

image

 

My own impression is that the eject-a-bed presentation was just OK – I had network problems so people could not see it in action.  Also, the presentation was about PWMs and servos and I should have had one slide explaining what PWMs are and one slide explaining what servos are and how to program them.  There were about 10 people in that session.

The F# presentation also was OK+ – I had 30+ people in the room and there were some great comments/questions (esp from Jim Christopher).  I think I said “I don’t know” about 4-5 times over the hour and a half – which is better than trying to BS something.  At the end, 3 people said they were interested in doing a F#/Analytics SIG at TRINUG so perhaps we can get some critical mass going.

Finally, Lobbyguard was a sponsor so we had a kiosk in the lobby doing sign ins.  When the conference was over, I took the registrations and compared it to the people who signed into the kiosk.  Appx 50% of the registered people showed up.  There does not appear to be any correlation between when a person signed up and if they attended.

image

 

image

Also, here is the registrations by time (rounded to the nearest 15 minutes)

image

(The keynote started at 8AM and the 1st session was at 9AM)

Note that 60% of attendees where here by the keynote and 93% of our attendees where here by the 1st session.  We shut the kiosk down at 10:30 so there might have been some stragglers after that.  There are 2 possible action items coming out of this:

1) Should TRINUG start the code camp later so that more people attend the keynote (or put the keynote in the middle/end of the day)?

2) What should TRINUG do to increase the attended/registered ratio?  There was lots of food left over – which is a waste.  If you have an idea, just shoot me an email (jamie@tenfingersfree.com) or leave it on this blog.

Tech Jam and Team Islington Green

IslingtonGreen

 

So a couple of friends from TRINUG – Ian Cillay and David Green – invited me to join them at a 36 hour continuous code fest called Tech Jam. Tech Jam was put on Met Life and the Department of Veterans Affairs on Nov 1 and 2 in RTP. This team of 3 developers was joined by Ian Henshaw who helped with some primary data provision and much of the user story development. David handled the MongoDB part, Ian took care of the UI (Bootstrap and Knockout), and I did the analytics (F# and R) and security piece.

The problem domain was that the Veterans Administration has this format of medical records called Blue Button. Blue Button is an unstructured format which make typical parsing and analysis very difficult. Here is a sample:

clip_image002

Also, the VA wanted some kind of mutli-platform solution that a vet can use that can make sense of this data and allow him/her to provide it to a care giver when needed.

Some random thoughts about the contest:

  • MongoDB makes a lot of sense for the data because of it being so unstructured. Note that the VA has now introduced BlueButton+, which is XML format – so that is a step in the right direction. I was impressed how easy Mongo was to use and how powerful it is to tackle unstructured data – but note that even MongoDb still needs some kind of structure – just not xNF relational…
  • Bootstrap was awesome – we used an out of the box template and it was great to knock out an easy design.
  • F# made analytics and predictive analysis a snap. 
  • There were 15 teams registered, 10 actually presented at the end. There were 2 community teams (us and another), 1 high school team (awesome), and a bunch of corporate teams (Deutsche Bank, IBM, Tata(X3!), etc…).
  • One of the teams (Infusion) was a vendor for Met Life already (they worked on the wall project and the infinity project). Unsurprisingly, they won the grand prize.  My only comment on that is that civic/community hackers already view events like this with a skeptical eye – and this did nothing to help MetLife in the eyes of those kind of people – in fact probably did the opposite.
  • I was amazed by how many teams did not actually address the primary problems that the VA needed fixed.  The problems were taming unstructured data and presenting it in a platform-agnostic way.  Most teams used HTML5/Phonegap for req #2 – which is the easier one.  I think only 3 teams actually addressed requirement #1?
  • I am proud to say that my team did address both requirements.  As I sometimes say “I listen to two things in life: my wife and the requirements.  It goes better for me if I do that.”
  • Another team was from a company where the boss showed up on Saturday to present the team’s work. I guess that is the difference with a corporate hack-a-thon.  Also, you can tell the corporate teams because they had more powerpoint and less code in their final presentation.  Not that there is anything wrong with that….
  • The best line this weekend was when I asked a D level person at Metlife why no one at Metlife was retweeting my tweets with their hashtags (#techjam) and he said "we have a guy for that." Sure enough, they had 1 person who was their tweet guy.
  • MetLife really know how to put on a contest. The MC for this – Gary Hoberman – was awesome – a V-Level techie that really could communicate with the coders. The food was good (they took into account different dietary needs), the working space was good and the swag was useable.  Also, they had dev mentors circulating around the room, though they seemed to spend their time with other teams – so we didn’t interact with them.  They also had reps from MongoDB and MSFT helping out – which is great because we leaned on them for specific problems.

The problem with a code contest is that you have little time to learn from your fellow devs – it is pretty much heads down and check-in. In any event, the best part was hanging out great developers like Ian and David and working on a worthwhile project for our country’s vets.  At the end, it was a fun time and my team delivered that the VA can use to springboard into a real application.

A tale of two web hosting companies

So as a Microsoft duh-veloper, I spend most of my time in the Microsoft stack, drinking from the fire hoses that stretches across the country from Redmond.   Recently, I had an experience that made me want to turn off the hose for one of their products.

I signed up for Azure last year with a trial account so I could participate in Rock,Paper, Azure.  I managed to get some of my co-workers to signup also and we had a good time competing against each other.  I then canceled the subscription once the contest was over.  A couple of months later, I spun up a new instance of Azure for Open Data day – trying to convince people to use Azure to host their data and expose public data to the rest of the world.  The problem was that since I used my same credit card to sign up, I could not use the free 90 day trial, so I signed up for a pay-as-you-go one.  After Open Data Day was over, I took down the site.  Finally, at Tech Ed I met some people who were wondering about the cloud so I spun up an instance of Azure and Team Foundation Service so they can see if in action.  After Tech Ed, I spun down that sight.

Meanwhile, each month, Azure was generating a service charge for a site that was not active.  When I realized it (about 4 months later), I emailed the Azure team and asked that they refund the money because:

1) I was not using any site for anything real and the traffic logs confirm that

2) I was actually doing grass-root marketing for them.

Their response?  No way!  Perhaps it was because they had earnings coming up and my couple of hundred of dollars had a material impact on the 80.37 Billion in annual revenue they reported – I never under estimate the power of compound interest.  In any event, I appealed the decision to the manager and his/her response?

image

I then hit up our local developer evangelist.  He took a look and and got no where too (and I thought the DE were like the political commissioners/Darth Vaders and could bend the bureaucracy with their mind powers). 

In any event, it was all right there – I should have turned off the site completely and I was at fault for not watching my account (and credit card statement) closely.  Fair enough, I made the mistake and really have no one to blame but myself.  I can already hear Rob Seder telling me that I could sign up for biz spark so I wouldn’t have been charged – but I guess I am more annoyed on how Microsoft treats the developers than how I could have avoided the fees.

I contrast this experience with another one I had this week with WinHost.  I was running a site for a local group when the renewal came up.  The group was done so the site was coming down – I put it on my life’s //TODO list to cancel the site.  By the time I got to it – the site had renewed and the card had been charged.  I immediately emailed their support and within 20 minutes, I had this in my inbox:

image

The thing is, WinHost didn’t have to refund the money – and they did anyway:

image

So the conclusions I draw are:

1) I am not going to recommend Azure for side-development to other devs and companies.  It is a great platform – but it sure seems like Microsoft has lost its way in how it treats developers who use their technologies.

2) WinHost is awesome and I will continue to use them for web site and web Service hosting – and any new sites I do I will start on Win Host.

Self-Referencing Keys Gotcha in EF

Looking at the Employee table in Northwind, there is a self-referencing key on the ‘ReportsTo’ field

image

When a series of new employees are created, you might run into problems trying to commit those changes all at once.  For example:

  1. static void Main(string[] args)
  2. {
  3.     Console.WriteLine("Start");
  4.  
  5.     using (NorthwindEntities entities = new NorthwindEntities())
  6.     {
  7.         Employee employee1 = new Employee();
  8.         employee1.FirstName = "Test";
  9.         employee1.LastName = "Employee1";
  10.         entities.Employees.Add(employee1);
  11.  
  12.         Employee employee2 = new Employee();
  13.         employee2.FirstName = "Test";
  14.         employee2.LastName = "Employee2";
  15.         employee2.ReportsTo = employee1.EmployeeID;
  16.         entities.Employees.Add(employee2);
  17.  
  18.         entities.SaveChanges();
  19.     }
  20.  
  21.     Console.WriteLine("-Stop-");
  22.     Console.ReadKey();
  23. }

 

When you run this, you get this kind of exception:

image

 

The reason is that the PK of the 1st employee is 0 and the PK of the second employee is ….. 0.  Since both are created on the client and have not had the ‘real’ primary key assigned by the database, the FK gets confused because there are 2 Primary Keys with the same value.  And according to these calculations, that is impossible.

The way to fix this problem is to move the SaveChanges() to after each add like this:

  1. using (NorthwindEntities entities = new NorthwindEntities())
  2. {
  3.     Employee employee1 = new Employee();
  4.     employee1.FirstName = "Test";
  5.     employee1.LastName = "Employee1";
  6.     entities.Employees.Add(employee1);
  7.     entities.SaveChanges();
  8.  
  9.     Employee employee2 = new Employee();
  10.     employee2.FirstName = "Test";
  11.     employee2.LastName = "Employee2";
  12.     entities.Employees.Add(employee2);
  13.     employee2.ReportsTo = employee1.EmployeeID;
  14.     entities.SaveChanges();
  15.  
  16. }

Or to not associate the FK until the 1st bulk commit like this;

  1. using (NorthwindEntities entities = new NorthwindEntities())
  2. {
  3.     Employee employee1 = new Employee();
  4.     employee1.FirstName = "Test";
  5.     employee1.LastName = "Employee1";
  6.     entities.Employees.Add(employee1);
  7.  
  8.     Employee employee2 = new Employee();
  9.     employee2.FirstName = "Test";
  10.     employee2.LastName = "Employee2";
  11.     entities.Employees.Add(employee2);
  12.     entities.SaveChanges();
  13.  
  14.     employee2.ReportsTo = employee1.EmployeeID;
  15.     entities.SaveChanges();
  16.  
  17. }

Switch Databases Using EF: Part Deux

Consider you are a company where you want to keep each of your customer’s data in its own database on the same server.  Each of the databases has the identical schema.  For example:

image

In the Data Access Layer, you are using Entity Framework and you want to move between databases at run time.  I blogged about one possible solution to this problem here, but I was thinking about this some more and I have a different (better?) idea. 

The first thing to realize is that EF does not make this easy.  There is not a Contxext.ChangeDatabase(String) method and the constructor does not allow to pass in a connection string.  This tight-coupling smells of poor design, but fortunately this is not insurmountable.

The first step is to create a Model (NorthwindModel in this case).  When you inspect the context, you can see that Microsoft made the entities a partial class

image

So you can add a class to your project like so:

  1. public partial class NorthwindEntities
  2. {
  3.     public NorthwindEntities(String connectionString)
  4.     {
  5.         base.Database.Connection.ConnectionString = connectionString;
  6.     }
  7.  
  8. }

 

Then, in your consuming class, you can create a method like this:

  1. internal static String CreateConnectionStringWithCustomDatabase(String baseConnectionString, String database)
  2. {
  3.     SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder(baseConnectionString);
  4.     connectionStringBuilder.InitialCatalog = database;
  5.     return connectionStringBuilder.ToString();
  6. }

And then you can switch databases.  Just pass in the default connection string and the new database name like so:

  1. static void Main(string[] args)
  2. {
  3.     Console.WriteLine("Start");
  4.     String defaultConnectionString = "data source=DIXON12;initial catalog=TBD;integrated security=True;MultipleActiveResultSets=True";
  5.     String actualConnectionString = CreateConnectionStringWithCustomDatabase(defaultConnectionString, "Northwind");
  6.  
  7.     using (NorthwindEntities entities = new NorthwindEntities(actualConnectionString))
  8.     {
  9.         foreach (var product in entities.Products)
  10.         {
  11.             Console.WriteLine(product.ProductName);
  12.         }
  13.     }
  14.  
  15.     Console.WriteLine("-End-");
  16.     Console.ReadKey();
  17.  
  18. }

 

And you can change databases on the fly:

image

The ’gotcha’ to realize is that Entity Framework requires that you have a default value in the app/web.config file.  If not, you will get this exception:

image

This smells like too much coupling, but that is a common theme with EF.  So make sure you have a default EF connection string in the .config – even if you don’t even use it.

F# and C#: The cross-over syntax

As part of my F# presentation to the TRINUG code camp, I did Question #1 of Project Euler.  I started with a typical way a C# programmer might approach it: using mutable variables and looping.  Something like this:

  1. public static Int32 TryOne()
  2. {
  3.     List<Int32> selectedNumbers = new List<int>();
  4.     for (int number = 0; number < 1000; number++)
  5.     {
  6.         if (number % 3 == 0)
  7.         {
  8.             selectedNumbers.Add(number);
  9.         }
  10.  
  11.         if (number % 5 == 0)
  12.         {
  13.             if (!selectedNumbers.Contains(number))
  14.             {
  15.                 selectedNumbers.Add(number);
  16.             }
  17.         }
  18.     }
  19.  
  20.     Int32 total = 0;
  21.     foreach (Int32 number in selectedNumbers)
  22.     {
  23.         total += number;
  24.     }
  25.  
  26.     return total;
  27. }

 

I then demonstrated they way a typical F# might approach the problem:

  1. open System
  2. let tryOne = [1..1000]
  3.                     |> Seq.filter(fun number -> (number%3 = 0 || number%5 = 0))
  4.                     |> Seq.sum

 

There are some differences worth noting.  The first is the terseness of F# and less “noise” of curley-braces and semi-colons.  The second is that the F# is more readable than the C# – assuming the person reading the code is not steeped in the java/C++/C# syntax.  Finally, there are less chance for bugs in the F# code.  In the C# code, there is a chance that selectedNumbers varaible might be altered and the total variable might be altered – esp. when doing the program in a multi-threaded manner.

Next, a more advanced C# developer might use Linq or Lambdas to write the answer like this:

  1. public static Int32 TryTwo()
  2. {
  3.     var total = Enumerable.Range(0, 1000)
  4.                         .Where(number => (number % 3 == 0) || (number % 5 == 0))
  5.                         .Sum();
  6.     return total;
  7. }

 

The similarity between this C# code and the F# code is striking.  The biggest difference is that the OO syntax makes the functions a part of the object being acted upon while the functional syntax makes the functions a part of a separate construct.  This change in perspective is the only real difference – and I am noticing that the more you look at code via the functional way, more mental doors are opened when solving a problem…

Relative Speed: F# v C# v VB.NET

(Spoiler alert: F# is faster – by alot)

As part of my presentation on F# which I hope to show at CodeCamp 2013, I did a quick speed test among C#, VB.NET, and F#.  I thought about Dr. Evil and how he tried to ransom the UN for “One Million Dollars”  and I thought about how the Federal Reserve is creating money from nothing to the tune of $40 Million a month via QE3 – so I built a quick app that does the exact same thing as the Federal Reserve does (except mine has unit tests, theirs probably does not).

I created a class for a Dollar bill (C#, VB, F#):

  1. public class Dollar
  2. {
  3.     public Int32 Id { get; set; }
  4.     public String SerialNumber { get; set; }
  5.     public Int32 FederalReserveDistrict { get; set; }
  6.     public Int32 SeriesDate { get; set; }
  7.     public String Signature { get; set; }
  8. }

  1. Public Class Dollar
  2.     Public Property Id As Int32
  3.     Public Property SerialNumber As String
  4.     Public Property FederalReserveDistrictNumber As Int32
  5.     Public Property SeriesDate As Int32
  6.     Public Property Signature As String
  7. End Class

  1. type dollar =
  2.     {Id: int;
  3.      SerialNumber: string;
  4.      federalReserveDistrict: int;
  5.      seriesDate: int;
  6.      signature: string}

I then implemented the same algorithm that the Federal reserve uses (C#, VB, F#):

  1. public List<Dollar> GetDollars(Int32 numberOfDollars)
  2. {
  3.     List<Dollar> dollars = new List<Dollar>();
  4.     Dollar currentDollar = null;
  5.     Random random = new Random();
  6.     for (int i = 0; i < numberOfDollars; i++)
  7.     {
  8.         currentDollar = new Dollar();
  9.         currentDollar.FederalReserveDistrict = random.Next(1, 13);
  10.         currentDollar.Id = i;
  11.  
  12.         String serialNumber = String.Empty;
  13.         for (int j = 0; j < 9; j++)
  14.         {
  15.             serialNumber += random.Next(0, 9).ToString();
  16.         }
  17.         currentDollar.SerialNumber = serialNumber;
  18.         currentDollar.SeriesDate = 2000 + random.Next(0, 10);
  19.         dollars.Add(currentDollar);
  20.     }
  21.     return dollars;
  22. }

  1. Public Function GetDollars(ByVal numberOfDollars As Int32) As List(Of Dollar)
  2.     Dim dollars As New List(Of Dollar)()
  3.     Dim currentDollar As Dollar = Nothing
  4.     Dim random As New Random()
  5.     For dollarIndex As Integer = 0 To numberOfDollars – 1
  6.         currentDollar = New Dollar()
  7.         currentDollar.FederalReserveDistrictNumber = random.Next(1, 13)
  8.         currentDollar.Id = dollarIndex
  9.  
  10.         Dim serialNumer As String = String.Empty
  11.         For serialNumberIndex As Integer = 0 To 9
  12.             serialNumer += random.Next(0, 9).ToString()
  13.         Next
  14.  
  15.         currentDollar.SerialNumber = serialNumer
  16.         currentDollar.SeriesDate = 2000 + random.Next(0, 10)
  17.         dollars.Add(currentDollar)
  18.     Next
  19.     Return dollars
  20. End Function

  1. type dollarProvider() =
  2.     let randomNumberGenerator = new System.Random()
  3.     let createSerialNumber =
  4.         List.init 9 (fun _ -> randomNumberGenerator.Next(0,9))
  5.                                     |> Seq.map string
  6.                                     |> String.concat ""
  7.     let createDollar id =
  8.         let returnDollar = {Id=id;
  9.             SerialNumber= createSerialNumber ;
  10.             federalReserveDistrict=randomNumberGenerator.Next(0,13);
  11.             seriesDate=2000+randomNumberGenerator.Next(0,9);
  12.             signature=""}
  13.         returnDollar
  14.     member this.GetDollars (numberOfDollars:int) =
  15.         List.init numberOfDollars (fun index -> createDollar index)

I then created a WPF I with the following XAML:

  1. <Grid>
  2.     <Button Content="Run C#" Height="32" HorizontalAlignment="Left" Margin="12,97,0,0" Name="CSharpButton" VerticalAlignment="Top" Width="95" Click="CSharpButton_Click" />
  3.     <TextBox Height="20" HorizontalAlignment="Left" Margin="12,150,0,0" Name="CSharpResultsTextBox" VerticalAlignment="Top" Width="95" />
  4.     <Button Content="Run VB" Height="29" HorizontalAlignment="Left" Margin="120,99,0,0" Name="RunVBButton" VerticalAlignment="Top" Width="99" Click="RunVBButton_Click" />
  5.     <TextBox Height="19" HorizontalAlignment="Left" Margin="117,150,0,0" Name="VBResultsTextBox" VerticalAlignment="Top" Width="102" />
  6.     <Button Content="Run F#" Height="28" HorizontalAlignment="Right" Margin="0,99,162,0" Name="RunFSharpButton" VerticalAlignment="Top" Width="105" Click="RunFSharpButton_Click" />
  7.     <TextBox Height="22" HorizontalAlignment="Left" Margin="239,147,0,0" Name="FSharpResultsTextBox" VerticalAlignment="Top" Width="102" />
  8.     <Label Content="Number Of Dollars" Height="30" HorizontalAlignment="Left" Margin="12,18,0,0" Name="label1" VerticalAlignment="Top" Width="115" />
  9.             <TextBox Height="24" HorizontalAlignment="Left" Margin="126,22,0,0" Name="DollarsTextBox" VerticalAlignment="Top" Width="115" Text="1000000" />
  10. </Grid>

and Code Behind

  1. private void CSharpButton_Click(object sender, RoutedEventArgs e)
  2. {
  3.     Stopwatch stopWatch = new Stopwatch();
  4.     stopWatch.Start();
  5.     CS.DollarProvider provider = new CS.DollarProvider();
  6.     Int32 numberOfDollars = Int32.Parse(this.DollarsTextBox.Text);
  7.     provider.GetDollars(numberOfDollars);
  8.     stopWatch.Stop();
  9.  
  10.     this.CSharpResultsTextBox.Text = stopWatch.Elapsed.TotalSeconds.ToString() + " seconds";
  11.  
  12. }
  13.  
  14. private void RunVBButton_Click(object sender, RoutedEventArgs e)
  15. {
  16.     Stopwatch stopWatch = new Stopwatch();
  17.     stopWatch.Start();
  18.     VB.DollarProvider provider = new VB.DollarProvider();
  19.     Int32 numberOfDollars = Int32.Parse(this.DollarsTextBox.Text);
  20.     provider.GetDollars(numberOfDollars);
  21.     stopWatch.Stop();
  22.  
  23.     this.VBResultsTextBox.Text = stopWatch.Elapsed.TotalSeconds.ToString() + " seconds";
  24.  
  25. }
  26.  
  27. private void RunFSharpButton_Click(object sender, RoutedEventArgs e)
  28. {
  29.     Stopwatch stopWatch = new Stopwatch();
  30.     stopWatch.Start();
  31.     FS.dollarProvider provider = new FS.dollarProvider();
  32.     Int32 numberOfDollars = Int32.Parse(this.DollarsTextBox.Text);
  33.     provider.GetDollars(numberOfDollars);
  34.     stopWatch.Stop();
  35.  
  36.     this.FSharpResultsTextBox.Text = stopWatch.Elapsed.TotalSeconds.ToString() + " seconds";
  37. }

 

And the results are pretty revealing:

image

 

I acknowledge that you can jerry rig C# to improve performance – esp using Pointers and the GOTO statement.  This exercise was to show performance doing the commonly-accepted way to solve a problem in each language (without FxCOP yelling at you).  It was not designed to see how clever you can get with C# to match the performance of the F# implementation.  As Rob Seder said “You can also bang in a screw by turning around the screwdriver and whacking away.”  If you need speed, F# is the best tool for the job.

Handling images in WebApi

I am digging into WebApi (v1) and one of the issues I was facing was images – specifically how to handle images.  I spent a fair amount of time researching the possibilities over the last couple of days and this is what I think I think.

1) You can include your image in your JSON payload like this:

  1. public class Person
  2. {
  3.     public Int32 PersonId { get; set; }
  4.     public String FirstName { get; set; }
  5.     public byte[] Image { get; set; }
  6. }

 

or you can include the imageUri in your JSON payload like this:

  1. public class Person
  2. {
  3.     public Int32 PersonId { get; set; }
  4.     public String FirstName { get; set; }
  5.     public String ImageUri { get; set; }
  6. }

 

The advantage of the former is that you can make 1 POST or GET call and get all of the data.  The disadvantages are that the image gets serialized into a large size and your service can get bogged down processing images when the rest of the payload is very small.

The advantage of the later is that you can separate the image into its own location – in fact not even use a Controller, and the processing is snappy-pappy.  The downside is that you need to make 2 GETs and POSTs for any given person (in this example).  For the POST, there is the additional factor that you have to wait for the 1st post to complete so you can get some kind of association key returned so that both POSTs can be associated together  I was talking to fellow TRINUG member Ian Hoppes about problem and he came up with a great idea – have the client generate a GUID and then push both POSTs at the same time.

In any event, if you separate the payload into two POSTS, you need a way of handling the image alone.  In WebApi V1, there seems to be 3 different ways you can do this:

  • A Controller
  • A Handler
  • A Formatter

I wasn’t sure what was the <right> answer so I posted this question to stack overflow – and no one answered it (at the time of this writing).  Left to my own devices, I decided to use an image controller so that the API has consistent implementation.

I newed up an Image Controller and added 3 methods: GET, POST, and DELETE.  The GET was pretty straight foreward (I used a Int32 on the parameter because I haven’t implemented the GUID yet):

  1. public HttpResponseMessage Get(int id)
  2. {
  3.     var result = new HttpResponseMessage(HttpStatusCode.OK);
  4.     String filePath = HostingEnvironment.MapPath("~/Images/HT.jpg");
  5.     FileStream fileStream = new FileStream(filePath, FileMode.Open);
  6.     Image image = Image.FromStream(fileStream);
  7.     MemoryStream memoryStream = new MemoryStream();
  8.     image.Save(memoryStream, ImageFormat.Jpeg);
  9.     result.Content = new ByteArrayContent(memoryStream.ToArray());
  10.     result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
  11.  
  12.     return result;
  13. }

 

The DELETE was event easier:

 

  1. public void Delete(int id)
  2. {
  3.     String filePath = HostingEnvironment.MapPath("~/Images/HT.jpg");
  4.     File.Delete(filePath);
  5. }

 

 

The POST, not so easy.  My first attempt was to read the steam and push it into an Image:

  1. public void Post()
  2. {
  3.     var result = new HttpResponseMessage(HttpStatusCode.OK);
  4.     if (Request.Content.IsMimeMultipartContent())
  5.     {
  6.         StreamContent content = (StreamContent)Request.Content;
  7.         Task<Stream> task = content.ReadAsStreamAsync();
  8.         Stream readOnlyStream = task.Result;
  9.         Byte[] buffer = new Byte[readOnlyStream.Length];
  10.         readOnlyStream.Read(buffer, 0, buffer.Length);
  11.         MemoryStream memoryStream = new MemoryStream(buffer);
  12.         Image image = Image.FromStream(memoryStream);
  13.     }
  14.     else
  15.     {
  16.         throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
  17.     }
  18. }

 

No dice, because the stream includes things other than the image binrary.  My second attempt was to use the MutlipartFormDataStreamProvider (which is the most popular way apparently) like so:

  1. public Task<HttpResponseMessage> Post(int id)
  2. {
  3.     if (!Request.Content.IsMimeMultipartContent())
  4.     {
  5.         throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
  6.     }
  7.  
  8.     string root = HttpContext.Current.Server.MapPath("~/Images");
  9.     var provider = new MultipartFormDataStreamProvider(root);
  10.  
  11.     var task = Request.Content.ReadAsMultipartAsync(provider).
  12.         ContinueWith<HttpResponseMessage>(t =>
  13.         {
  14.             if (t.IsFaulted || t.IsCanceled)
  15.             {
  16.                 Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
  17.             }
  18.  
  19.             foreach (MultipartFileData file in provider.FileData)
  20.             {
  21.                 //Trace.WriteLine(file.Headers.ContentDisposition.FileName);
  22.                 //Trace.WriteLine("Server file path: " + file.LocalFileName);
  23.             }
  24.             return Request.CreateResponse(HttpStatusCode.OK);
  25.         });
  26.  
  27.     return task;
  28. }

 

I don’t like this because I am writing to disk first – and I don’t need to use the file system – in fact, it might be locked down in some scenarios.  So finally, I cobbled together some posts and found a way to read the parsed stream and create an image without using disk:

  1. public HttpResponseMessage Post()
  2. {
  3.     var result = new HttpResponseMessage(HttpStatusCode.OK);
  4.     if (Request.Content.IsMimeMultipartContent())
  5.     {
  6.         Request.Content.ReadAsMultipartAsync<MultipartMemoryStreamProvider>(new MultipartMemoryStreamProvider()).ContinueWith((task) =>
  7.         {
  8.             MultipartMemoryStreamProvider provider = task.Result;
  9.             foreach (HttpContent content in provider.Contents)
  10.             {
  11.                 Stream stream = content.ReadAsStreamAsync().Result;
  12.                 Image image = Image.FromStream(stream);
  13.                 var testName = content.Headers.ContentDisposition.Name;
  14.                 String filePath = HostingEnvironment.MapPath("~/Images/");
  15.                 String[] headerValues = (String[])Request.Headers.GetValues("UniqueId");
  16.                 String fileName = headerValues[0] + ".jpg";
  17.                 String fullPath = Path.Combine(filePath, fileName);
  18.                 image.Save(fullPath);
  19.             }
  20.         });
  21.         return result;
  22.     }
  23.     else
  24.     {
  25.         throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
  26.     }
  27.  
  28.  
  29. }

 

Note that I am using a disk right now on the POST and GET but I am going to swap it out with Azure Blob Storage.  That way I can just create the image and push it over to Azure without my local disk being used at all.

Sure enough, this works like a champ. The GET

image

and the POST (using Fiddler – you have to use the most recent Fiddler so you get the [Upload File] link):

image

image

Another note is that I am pushing the UniqueID of the image in the request header – not in the content’s header.

This works:

  1. (String[])Request.Headers.GetValues("UniqueId");

This does not:

  1. var testName = content.Headers.GetValues("UniqueId");

F# List of String Manipulation

I am learning a valuable lesson about stack overflow – if I write down my question 1st and then search the key words using my favorite search engine, I can sometimes find the answer.

For example, I wanted to turn a list of string into 1 long string: ["A"; "B"; "C"] becomes “ABC”

I first tried via the functions found in the List class:

  1. let stringList = ["A"; "B"; "C"]
  2. let sumValues = List.sum stringList

 

The problem was I got the Red Squiggly Line Of Approbation on the stringList

 image

So then I typed a question for stack overflow with the words “string concatenation” and then I thought to try and try that into Google.  The 1st result was this: http://msdn.microsoft.com/en-us/library/ee353761.aspx

And low and behold, the example is exactly what I want to do

  1. let stringList = ["A"; "B"; "C"]
  2. let sumValues = String.concat "" stringList

image

I then applied that to a list of ints:

  1. let intList = [0..10]
  2. let concatValues =
  3.     intList
  4.     |> Seq.map string
  5.     |> String.concat ""

 

and after feeling good about figuring this out, I immediately began wondering how I can reduce that to 1 line of code

Smile

F#: “Unexpected InFix” and “Incomplete value”

Dear Future Jamie:

If you are doing some pipe forwards like this:

  1. let createConcatRandomList = List.init 9 (fun _ -> randomNumberGenerator.Next(0,9))
  2.     |> Seq.map string
  3.     |> String.concat ""

 

and you are getting this:

image

with the RSLA  on the let saying:

Incomplete value or function definition. If this is in an expression, the body of the expression must be indented to the same column as the ‘let’ keyword.

and the RSLA on the |> saying:

Unexpected infix operator in binding. Expected incomplete structured construct at or before this point or other token.

Then your pipe is in the wrong place.  Tab it over to inside the List like this:

  1. let createConcatRandomList = List.init 9 (fun _ -> randomNumberGenerator.Next(0,9))
  2.                                 |> Seq.map string
  3.                                 |> String.concat ""

 

Love,

Current Jamie

 

PS: you really should exercise more…