Saturday, December 21, 2013

Are you ready for Christmas?

1686445_stock-photo-pile-of-gift-boxes

Jerk: Noun. Slang. a contemptibly naive, fatuous, foolish, or inconsequential person.

I have to admit, I can be a jerk.  Sometimes we all do things mistakenly that come across as arrogant or conceited, but doing them mistakenly is sometimes allowed, as we are all human.  Being a “jerk” however, is when we do things that are not mistaken, but rather on purpose.  One could say that doing something on purpose to intentionally harm one another is grounds for psychiatric evaluation.  In that regard, the past few weeks.. I have been a self proclaimed “jerk”.

I’ve had this little social experiment going on recently.  Christmas is a busy time of year. Professionally, we have the end of the year goals that we are all concerned about, if it’s finishing projects, cleaning things up, raising cash to meet goals, we all have pressures that turn into pumpkins Dec 31 at midnight.  Personally, we fill the little free time we have left with shopping, list-making, cleaning, etc.  Once our shopping is done, we have to make preparation with the gifts we buy and package them neatly.  Many of us host family and friends during this time, so we need to ensure food is cooked and served.  And of course, we tend to travel as well, so normally we all arrive on location somewhere and bring said gifts, and possibly said food, and run around.  Sound familiar?  I’m sure it does..

So, my social experiment.. every person I’ve had a chance to chat with.. checkout lady at the market, friends at work, barista filling my coffee order, the woman cutting my hair.. if I was making small talk, I asked one question, “are you ready for Christmas?”  The “jerk” part of me prompted me to ask this because my family shopping has been done for weeks now.  It feels good to not have to stress about last minute gifts, or visit a Toys R’ Us that is conveniently open 24 hours a day for those who still have stockings to stuff.  The social experimental part of me wanted to see what people have said.

pillar-burning-honey-candles  I got a variety of looks and responses as I did this.  The more frenzied looks and responses came, obviously, as the date got closer and closer to the number “24”.  Most responses were “oh I haven’t even started yet”.  A few involved something along the lines of “I need to bake, so hopefully I get that done soon”.  But one gentleman I spoke to said “I’m done.. I don’t shop”.  Obviously, he was the most peaceful of all respondents.

As indicated on Wikipedia, Christmas is Old English for “Christ’s Mass”, and serves as the annual celebration for the birth of Jesus Christ.  It’s expected that this annual feast has been celebrated as early as 354 AD, and has had a range of activities from raucous drunkenness in the dark ages, to a more recent “family friendliness” approach.  It was once common to give a gift of a “Yule Log”, which was a very hard piece of wood that would provide warmth and light during the 12 days of Christmas celebration, but more recently, the “Yule Log” designation has been the gift of a fruit cake… how classy.

Roman mythology has celebrated and recognized many gods and goddesses, most of which are now well known thanks to the popularity of the “god of war” video game series (it’s amazing how some of us get our history knowledge). One of the gods they celebrated was Saturn, and they celebrated it with the Saturnalia festival by allowing gambling, partying and private gift giving.  This festival took place on December 23rd, 2 days within the “Christ’s Mass feast”.

The gentleman who told me he doesn’t shop went on to tell me that none in his family shop for the holidays.  Their family is large, and their parents have more than enough money that it’s unnecessary for anyone to shop for them, as anything they want they can easily purchase for themselves.  I asked “what are your plans for the holidays?”, and he told me they’ll still get together, spend time with one another and enjoy the day, but gift giving is not on the list. 

I stated earlier.. I shopped.  I spent money, and probably spent more than I should.  Quite frankly, I’m alright with that, as I also believe in the spirit of giving, and am very excited to give my daughter, wife, parents, brother, in-laws, and extended family their gifts.  I know in turn they will all give me presents, most of the things I’ll be surprised with, some I won’t.  But shortly after the gift giving, we’ll spend time, talk, drink, laugh, celebrate, drink, sleep, and do it all over again over the next few days (we’re not hardened alcoholics, we just have a large family and all tend to host lunch\dinner during the Christmas-New Years time period).

Christmas is a celebration, and is intended to dedicate a day to the idea that the savior of the world has been born, in humbling circumstances, to some day redeem us all.  Some of us believe this, some of us don’t, but regardless it is a wonderful story that gives us all hope.  This celebration was never intended to give retail stores a gross annual profit, give employees a chance to make “time and a half”, and keep employees separated from their families because people need to shop at Toys R’ Us 24 hours a day.  I’m not challenging anyone to do anything I don’t do, but for those of you who feel like you’re shopping to shop, stop shopping.  For those of you who are running around and looking to make the pile under the tree larger, stop.  If you want a gift, give the gift of time.  Spend time with one another, reach out to those who you haven’t spoken to, and invite those into your home who you have.  Want a novel idea?  Take a collection from all family members and use the money to give a donation to a food bank, or to St. Judes, or to a family member in need, or to anything that you can all agree on. 

For those of you who have shopped, I don’t intend to demean you (I’m one of you, remember?)  But hopefully this post offers a little guidance and insight on how we have gone from “He is born!” to “24 hours of super saving on all blue light items!”  What we all need is time, and what we all spend is the time we don’t have worrying about the things that aren’t important. Starting in 2014, take some time to focus on what is important instead.

Sunday, December 15, 2013

Are “Apps” Dumbing Us Down?

I had some sort of epiphany, if you will,  recently.  My wife and I bought our daughter a small bookshelf for her room… that we preceded to put together and store toys on it.

WP_20131212_002 I wish I took a picture of all of the pieces before we assembled this thing.  It looks pretty in pictures, but individually, the box of “stuff” weighed 75 lbs. and contained about 20 individual blocks of wood.  Then there was the mess of screws, nails and cam bolts required as well, all packaged in one plastic bag that had to be separated manually.  I didn’t take a picture before I assembled the shelving, because I didn’t have my aforementioned epiphany until as I was assembling the unit.

Where I work, our CEO loves apps.  I mean, he is absolutely enamored with them.  I can’t limit that statement to apps either, it’s really Apple he is crazy about as well, and he lights up like a kid on Christmas whenever there’s a new phone or tablet being announced.  Before they even announce the features.. he wants it.  He almost doesn’t care about what the features will be… he believes ahead of time they’ll be distinctive, smart and critical to the success of the latest implementation of the device.

Here’s why he really loves Apple though.. he loves the simplicity.  And I can understand that.  Being a software developer, Apple is a pain in my rear-end. Why?  They upped the ante when it comes to user experience and design.  I’m not a designer, I can make my way through those needs when developing applications,  but before Apple, textboxes and pictures were “good enough”.  Now, a simple checkbox isn’t good enough, it must “toggle”.  Animation isn’t a nice touch, it’s now necessary.  Simple “alert” windows are ugly, modal windows are the way to go. 

With Apple, everything is just “a click”, “a tap”, or now just “a command” in that it’s easy to just speak to Siri what you want.  This is like.. Jetson’s stuff, man!  But this brings me to the title of this post.. is this dumbing us down?  What does this simplicity due to our psyche?  Not just from a technology standpoint, but from how we approach problem solving as well?  Furthermore, what about our usage of the Internet, and Google?  It’s *amazing* that we can Google (verb tense) “How do I ask a girl out?” and get tips! 

Apple used to use the phrase “Think Differently”, but are we really thinking anymore?  Or are we just zombified by all of this technology?  I don’t have an answer to the questions in this blog post, more or less I’m trying to remain cognizant of the potential downfalls of simplicity, and I hope you do as well.  I don’t want to live in a society that is so used to simplicity that, over time, it’s considered a unique skill to have problem solving skills.  At this rate, are we only 1.. maybe 2.. generations away from having people not assemble shelving because there are too many pieces?  Or who knows, maybe they do it, only because there are step by step video’s on their phones.  Handy?  Sure.. sounds it.. but it sounds like it’s devolving us somewhat too.. doesn’t it? 

So the next time you’re faced with a problem scenario, challenge yourself to not just Google it, or call over a friend, or launch an app.  Think about it.. and I stress the term Think here.  Churning and using some brain power can do all of us some good…

Wednesday, November 20, 2013

Book Review – Strong Fathers, Strong Daughters: 10 Secrets Every Father Should Know

Strong Fathers, Strong Daughters: 10 Secrets Every Father Should KnowStrong Fathers, Strong Daughters: 10 Secrets Every Father Should Know by Meg Meeker
My rating: 5 of 5 stars

I had heard about Strong Fathers, Strong Daughters: 10 Secrets Every Father Should Know for quite some time now. If I'm not mistaken, the Dave Ramsey show had mentioned it numerous times as well, so it was always one of those books I wanted to get to "sooner or later". Admittedly, it became later, but I should have read this sooner.

I think this book not only helps transform a male into a positive role model for their daughter, but that it helps one become a positive role model for their wives as well. This book does an excellent job on presenting and\or reminding you on the challenges every woman faces these days, and the grit, maturity and dedication a father needs to have with their daughters to keep them balanced. Throughout the book, you are constantly reminded that the morals and self-respect you want your daughter to have are consistently challenged by all aspects of the world, from the commercials on TV to adverts in magazines she may thumb through at the checkout counter to text messages she may receive while you think she's sleeping in bed to the attention other girls get in school, which she craves as well. Additionally, the book also does a very good job on indicating how critical a father's support is in their daughters lives, as if those needs and approvals aren't found during adolescence and teenage years, it's only sought elsewhere from other guys as they get older.

Fortunately, the book offers simple solutions to many of these complex problems. Namely, it's that no matter what she sees or hears, she will always follow your guidance first, which is why it's so crucial to spend time with your daughter. The book also presents why it's equally important to talk with your daughter about the things that normally make you uncomfortable to talk about (I'll let you fill in those blanks), and that no matter how much she seems to resist you at times (namely teenage years), you still need to remind her that you're her father and that you know best. She may be bright, but you're more experienced, and while she may think she knows about guys, you *know* about guys.

All in all, the book makes a compelling argument to challenge your assumptions on what's important in life, and what's important to you. Determine your moral code, whatever that may be, and live it. As she grows older, indicate those same principles to her, and if you practice what you preach, there's a higher chance she'll listen. (It's even suggested to take the time and "write down" our own "commandments" if you will, so they're crystal clear to her.. and you.. on what principles should be abided as she grows and matures). If you don't want her to think women shouldn't be objectified, don't watch pornography. If you don't want her having pre-marital sex, don't get her birth control "just incase". If you don't want her drinking with friends at parties, don't get drunk yourself. In the end, the responsibility of a father is a huge one, but this book helps you realize that, and how important it is to take that responsibility seriously. I highly recommend this book for anyone who has a daughter.. or even wants to psychologically understand their wives more as well.

View all my reviews

Friday, November 8, 2013

Book Review – Dark Summit

Dark Summit: The True Story of Everest's Most Controversial SeasonDark Summit: The True Story of Everest's Most Controversial Season by Nick Heil
My rating: 3 of 5 stars

Admittedly, this book is outside of my normal non-fiction circle. I don't normally tend to read books that recount stories, etc. I gave this book 3 stars, as I considered it just that.. an average book. It was very well researched and documented, but this wasn't a book that was suspenseful as much as it was explaining the surrounding occurrences of numerous deaths on the worlds highest peak.

At the very least, it exposes our human nature when pushed to our extreme limits, as a number of individuals on Everest seem to have been either left for dead and\or passed by in their final hours, but the stories and recollections provided almost make you understand what that happened at least some of the time. I would argue that before reading this book, I too would wonder why so many we're left behind on the mountain, but only after reading this book I can understand that any rescue operation at that altitude, in that extreme cold, and under those conditions is just a completely different animal.

What I liked about this book was that it targeted and documented some history that in a way is forgotten. I imagine in 1996 these stories we're at least somewhat important, but now in 2013, I have yet to talk to anyone in passing and say "yeah, that's almost as bad as what happened on Everest in 1996". That's not to demean what happened for the lives lost, on the contrary it's to point out that just like we have "forgotten war's" in history, so too can other tragedies of different scales be lost in time. Nick Heil does an excellent job exposing the life and trials of those who arrange, organize and ultimately decide on who makes it back alive and how on Mt. Everest.

So why the 3 stars? I didn't find this book to be as much of a page turner as I did finding it to be reading a news story. Secondly, there are a lot of names in this book. Some of the "main characters" (I suppose you can call them that) are established early and referenced often. Others however are individuals mentioned briefly at times, whether they be one of the many who traveled up the mountain and were somehow associated with the story, while other's were one of the many Sherpas who were also involved in either a rescue attempt, or who had passed by a person thought to be dead. In the end, it was just a lot of sharing ideas, thoughts or comparison of stories over the issues and circumstances surrounding so many deaths. One Sherpa says "by the time I was there he was already frozen", a second says "he was barely breathing but we gave him oxygen to try and help", and meanwhile those running the operation from a base camp are trying to coordinate who's left on the mountain and if they have a chance to survive. Again, in all, it's some interesting stuff.. but not riveting or compelling in my opinion, but still interesting for anyone who either remembers the events that took place back in 1996, or those who are familiar with mountaineering and the camaraderie that typically goes with it.

View all my reviews

Tuesday, October 29, 2013

Enforcing JavaScript and CSS file refreshes on your ASP.NET website

A few years ago, I was part of a team that rolled out a website as part of a very large project.  The rollout on all aspects went reasonably well (except for one issue with a rather large page size, but we fixed that rather quickly).  One issue we had at launch however were some issues with existing users logging in for the first time.  Due to some funky logic we had in some JavaScript on our pages, some users were getting invalid error messages.  The bug was quickly identified and we rolled out the fix within an hour.  However, many of our users continued to have issues for hours after the fact.  The culprit was file caching.  In particular, our "login.js" file or whatever it was called was pushed to the web server, but web browsers were finding an existing file cached locally on the PC and were failing to download an updated version.
To force the new file to download, we went through all of our code, found references to all of our JS files (just to be safe) and appended a fake querystring value.  So our new code read as:
login.js?x=123

The querystring value can be arbitrary, just its presence gives the file a new name, and causes the web browser to detect a change and re-download the file, ignoring the cache.  However, now THIS file is now cached for some time, as all future references to login.js?x=123 will refer to the local copy.

So what if you want control over this programmatically?  Well, we have a few options.
The most basic method to handle this is to do what we did above, only add a value to your web config.  For example, add a configuration key called "CacheBuster".  In the ASP.NET world, it looks like this:
<add key="CacheBuster" value="X1235"/>
Now, you can refer to that value in our ASPX Markup, like so:
<script src="login.js?CacheBuster=<%=ConfigurationManager.AppSettings("CacheBuster")%>"></script>
This works for CSS files as well:
<link href="styles.css?CacheBuster=<%=ConfigurationManager.AppSettings("CacheBuster")%>" rel="stylesheet" />

See what we're doing there?  We're just referencing some value in our config file and appending it to our JS file reference.  Now, all references to the file will include our CacheBuster value.  So perhaps you are promoting a new website build and want to ensure that your users pull down the most current version of your JS or CSS files, you can just update the value in your config before deploying, and once the CacheBuster value has changed, it will ensure that all returning visitors get a new copy of your files.
Of course, we can do this from a timing perspective too.  Perhaps you want your users to pull a new file daily?  Just user the DateTime properties to create a unique value for that time period:
<script src="login.js?x=<%=DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString + DateTime.Now.Year.ToString()%>"></script>

This means that accessing the webpage today would provide "login.js?x=10292013", while accessing it tomorrow would result in login.js?x=10302013".  From this perspective, you have incredible flexibility.  You can use "Ticks" if you really wanted to to ensure that your users always pull the most current file (while also increasing all web traffic, of course).  Or, you can combine both methods listed above, giving a CacheBuster value along with a DateTime MMDDYYYY value, ensuring that you have flexibility on updating all cached copies of your JS and CSS files daily and\or whenever you promote a new build.
Hope this helps!

Thursday, October 24, 2013

Have other people test your code (and when it’s appropriate to use Hot Pink Comic Sans font)

I committed a mortal sin of mine recently, I chose not to let someone test some of my code.  I know better, but I was lazy, arrogant, aggravated, scared… you pick, it doesn’t matter, could be all of the above, either way, I should.. no.. do know better.

I’m working on a project that has been the most fun I’ve had in a long time.  I’ve gone shoulder deep in some jQuery\jQueryUI functionality on my front end UI, all managed by ASP.NET and hosted on Azure.  I’m performing AJAX JSON requests, updating HTML UI asynchronously based on user input, displaying modal windows, all stuff that nerdy people like me (and presumably you, since you are reading this) find cool.  I worked on a particular page for a few weeks.. not hours or days, but weeks.  I really put my heart and soul into getting a particular page.. what I thought was the crux of the site I’m developing, to function properly using the aforementioned technologies.  In the end, I was very happy, but thought of one or two features that would be helpful to have.  Namely, a “running total” of selected items (for all intents and purposes, think of this like a shopping cart “pick-a-product” page).  Since I recently finished the page, I knew what it took to get at the selected items, their prices, along with the additional options depending  on other items selected.  In the end, I was the only person looking at the site at this time and I told myself “eh, maybe phase 2”.

I know better…

I forwarded the site to my manager recently, and he was pleased with my progress, but he thought one or two elements were missing.  You guessed it, he thought we should display a running total and such.

Developer’s get involved in their coding process.  They rarely do the same thing twice, instead trying to use a slightly more efficient or updated methodology compared to a previous time.  When they encounter an issue, it becomes emotional.. it’s personal because it’s no longer programming but problem solving.  Some issues are solved in seconds.. others.. hours.  Combine that iteratively over each function on a website, app, whatever.. and you have many emotional hours invested in creating a Frankenstein… bringing something to life that once was never thought possible. 

In the end, when you finish writing code, it’s not a painting that dries and goes on display, it’s an evolving work that will change over and over and over.  The more important the software, the more change requests you’ll most likely receive.  Just because you work so hard at getting something “just right” doesn’t necessarily mean the software is just that.  Sometimes it’s best to ask your boss, co-worker, significant other or even your mother (no offense Mom!) their opinion on something.  At the end of the day, the only opinion that truly matters is your target audience.  If your demographic prefers Hot Pink Bold Comic Sans font.. well designer be damned.. put it on your site!

So if you’re reading this, and you develop software, get a second opinion on your software.  You may not always hear what you want to hear, but at least your software will meet the preferences of your end-users and not of the guys\gals that pieced it together, even if it did take them months to do so.

Wednesday, October 2, 2013

JavaScript Currency Formatter

I hate details.. that’s where the devil is.  I know it.. that’s what the saying says.  Nevertheless, the details are where many of my problems lie, yet I must continue to deal with them..  Today, my problem involved a number formatter, specifically a currency format.  A web app I’ve been working on is coming along rather smoothly, and using jQuery, jQueryUI and Twitter Bootstrap has given me some pretty cool UI features that I’ve been pleased with.  So, when it came to performing some custom validation and what-not, I started doing pretty cool things, like auto-formatting phone numbers and other numeric values while they were being typed. I then hit a wall, as I needed to apply numeric formatting to a currency value. This is apparently a sore spot for many others, so I thought I would share my Frankenstein creation of a currency formatter.

What did I build, well.. this: http://jsbin.com/IhUNAJo/2/embed?html,output

Glorious, right!?! Ehh, maybe not, but it's servicable, and I wanted to share it with the world. Here's the code:

How does this work? It's pretty simple. First, I'm using commafy, which is a prototype built by Steven Levithan. I'm using jQuery to capture the keyup\change events to alter my value (although this isn't necessary). Otherwise, I'm simply grabbing the current textbox value, stripping out anything that's not a number or a decimal value, adding comma's to the prefix (value before the decimal), and limiting the number to 2 values after the decimal.

Saturday, September 21, 2013

Get Column Name and Cell Contents of jqGrid on Double Click

I recently discovered the wonderful world of jqGrid, and what a wonderful world it is.  On several applications now, I’ve taken to implementing it in some sort of fashion, to either sort data or respond to various events to dynamically load data on my applications.  Today I had an issue, I needed to get the cell value and column label for the selected cell when a user double clicked in a jqGrid row.  onSelectRow makes this pretty trivial, but I didn’t want to respond to a single click, only a double click.  All the events and data required was built into jqGrid, I just couldn’t find much of anything on the web.  Hence, I figured it out, and thought I would offer my code to those who may be in need.

Instead of using onSelectRow and determining if it was a double click, etc, just use the onDblClickRow function, which offers the parameters rowid, iRow, iCol and e (for event).  Using this data, we can still access various arrays for your jqGrid and get at the appropriate cell value…

$(“#YourGrid).jqGrid({
   …
   ondblClickRow: function(rowid, iRow, iCol, e){
      var colNames = $(this).jqGrid(“getGridParam”, “colNames”);
      var colName = colNames[iCol];
      var colVal = $(this).jqGrid(“getCell”, rowid, iCol);
   }
});

And that’s all there is to it!

Friday, September 13, 2013

Creating a jqGrid with ASP.NET Web Forms and a JSON Web Service

I'm adding alot of twitter bootstrap, jquery and jqueryui components to a new project I'm working on, and frankly I'm pretty excited about how the UI is coming along.  At one point, I had the idea to use a jqGrid with my ASP.NET Web Forms application.  After some frustration, I eventually started to read various comments on stackoverflow and on other blogs, reading similar to:

  • Why cant I use jqGrid and ASP.NET?
  • jqGrid and ASP.NET... this is becoming mind numbingly painful
  • ASP.NET web service with jqGrid won't load, but no errors, whats the deal

My emotions were the same as being on the turnpike and being told "no rest stop for 50 miles" and then realizing your low on gas.  For anyone who has tried to use jqGrid with an ASP.NET web service, I'm sure you know what I'm talking about here, using jqGrid just seems to be very, very finicky.  Fortunately, many have prevailed, including me.  I wanted to give an honest to goodness example of using jqGrid and an ASP.NET web service (not using an HTTP Handler), since this was so painful for some reason.

High Level, how this works...

This works like you'd hope it would, set up some service to accept a request for data, and return that data request with JSON to the calling object.  Just 2 components to show here, a web service and a jqGrid calling the service.  Strap in..

ASP.NET JSON Web Service

Below is my example of the webservice object you need.  jqGrid is expecting something to come back with "total", "records", "page" and "rows", where rows has your items of data.  Here we create a response with these appropriate properties:

jqGrid

First off, before you even try to do anything else with your jqGrid, you need 3 things to make this thing work properly.  You may think you read their documentation and followed it to the letter of the law... but you're wrong.  Make sure you link to..

  1. A locale file (example: grid.locale-en.js)
  2. A jquery.jqGrid.js file
  3. A ui.jqgrid.css file
  4. (Bonus!) - Make sure you also link to jquery... just incase youre new to this stuff... and if so, place the jquery script reference first!

What's going on with that script?  It has all of the subtle nuances figured out for you, to prevent you from getting the same headaches many others have griped about.  Here's some of the main talking points:

  • Datatype is "json", since that's what we're expecting
  • In our example, no data is required for our service, so just send "{}" for the data parameter
  • ajaxGridOptions and contentType specifies application/json as the data transfer type, ensuring all data is sent as JSON and not XML
  • the serializeGridData function takes any data being posted to the web service and sends it as JSON, not XML.  I know what you're thinking, "I'm not sending any data I'll just delete this".. DONT.  Some basic data is always posted to the service when loading the grid, without this code, XML is sent instead of JSON, causing the jqGrid to freak out. 
  • jsonReader - this option contains all the little details in loading your grid with your data, setting your paging, etc.  Notice the "d." in the values, that's not a type-o, Microsoft and other services add this for security reasons (http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx).  Otherwise, these values just match to the properties we created in our webservice class

Wednesday, June 26, 2013

Windows Build 2013 Keynote - Thoughts From an Attendee

I'm fortunate enough to be in attendance at this years Microsoft Build conference, and this morning was the conference kickoff with the Day 1 Keynote led by Steve Ballmer.  Many bloggers and writers have already shared their notes, and they're all about Windows 8.1, read as: Start Buttons!  Search!  Touch!  Gestures!  Apps!

Author's are missing the point.  Yes, 8.1 was an important update, and it is definately bridging the gap between those who had pure touch devices running Windows 8, and those (like me) who had mouse\keyboard devices, also running Windows 8.  8.1 will make my laptop easier to use.. hooray.. but again, there was so much more to the keynote.

Several demo's took place this AM.  We saw a variety of hardware showcasing "old fashioned" Windows applications, newer Apps, enhanced GPU technology, Bing API's and services, and development tools that make porting applications easy, regardless if you're writing for a PC, a tablet, or a phone.  And THAT was the point of the keynote today.
 
Apple has had a novel concept for years, if you live within their eco-system, all your technology played very well together.  iPhone, iPad and Apple PC's would share data... music, video, pictures.. and communicate very well.  When the iPad came out, all of your apps that you already purchased for your iPhone were readily available.  The user experience never changed, one device was similar to another.  Microsoft has quickly invaded this same model.  Tablet, PC, Phone, or even your TV (XBox One) now will have the same experience.. the same apps, and the same functionality.  Want to share your music, video, or pictures?  Fine, go ahead, they're all available on SkyDrive for FREE mind you, just go ahead and copy your files up to the cloud.. if you wanted them available anytime, anywhere that is.

And that was the purpose of the Keynote today.  The future is bright for Windows 8.x, and not because of a Start button, but because Microsoft is going to regain it's momentum by relying on it's strength, that regardless of how many users have picked up Apple devices over the past 5 years, everyone has had a Microsoft device for 20.

Thursday, June 13, 2013

Top 5 Windows Phone Apps on Nokia Lumia 920

In a recent post, I professed my undying love for my Nokia Lumia 920, mainly for its beautiful camera, integration with social media (even though Im not a “social media” person) and seamless backup solution with SkyDrive.  I’ve had the phone for just over a month now, and I’m still very much a fan.  If you search “windows phone” and “apps” you’ll find a lot of negative press on lack of apps, and rightly so, since there are a 10th of the apps in their store than on iOS and Android.  However, that doesn’t mean the store is devoid of anything useful.  On the contrary, I’m disappointed that Microsoft\Nokia has done such a poor job on emphasizing what apps they do have, and how good they are.  If the title and intro paragraph here hasn’t informed you by now, I am here to do just that, providing you with a top 5 list of the best apps I have used thus far on my Nokia Lumia 920.

5. Transfer My Data

So here’s the situation, you already have a smart-phone, and have all of your contacts and images and what-not.  Nevertheless, you took the leap into the Windows Phone world, bought yourself a Lumia (such as my Nokia Lumia 920), and sat down ready for a tour-de-force 2 hours of migrating all of your content.  At this point, you should install Transfer My Data, run it, and figure out how you can spend your remaining 1 hour, 55 minutes of “transfer time”.  Transfer My Data is an insanely easy and smart app, where it connects with other devices via bluetooth, determine’s what type of device it has connected to, and then attempts to port over contacts, images, video, etc.  Granted, not all data will transfer over from every device, so it does depend what your source is, but either way, it’s a nice and semi-universal method of getting all of your content onto your new device.

4. OneNote

OneNote makes it onto this list for a few reasons.  Mainly, because it has native support on Windows Phone, which is very handy (read as it’s automatically installed).  The second reason is because OneNote on both Windows as well as Windows Phone supports free-form text, inserted images, and “lists” (just like the commercials, you can use checkboxes in the grocery store to determine what you have yet to purchase).  OneNote makes it very easy to jot down notes or keep track of data items on the fly… especially on a Lumia 920 which has a larger screen than standard smart-phones.  The third reason OneNote is among my top 5 apps is because of the Windows Phone SkyDrive integration.  Because it automatically communicates with the Microsoft Cloud Service, it feels very futuristic to have the ability to add\edit a list or compilation of data on your PC, head on down the road, and still have access to this information on your mobile device no matter where you’re heading to.  There’s no “sync my device”, restarting services, etc.  The phone automatically syncs for you, keeping all your data up to date.

3. PhotoBeamer

This is absolutely, positively an app that Nokia should be touting more (truth be told, it’s the inspiration for this blog post).  It’s not an app that I think will set the world on fire, or cause people to switch from iOS\Android to Windows Phone, I just think it’s a very slick interface, and something that is cool to use time to time.  So what is it?  On a PC, you go to photobeamer.com, and a large QR code is displayed.  You then open the PhotoBeamer app on your Windows Phone, choose an album to share pictures of, and are then given the ability to scan the QR code on the screen.  Once scanned, you can “beam” photo’s to the PC screen you visited the URL on.  So in essence, you can perform a slideshow of the images available on your phone, even with a cool “left to right” scrolling animation as you swipe through your photo’s.

2. SmartShoot

SmartShoot is one of many apps I have on my Lumia 920 that control the camera shots I take (apps for a camera are called “lenses”).  There are apps that let you take instagram-esque photo’s, or combine several shots to create a panoramic photo, but I ranked SmartShoot as my top app (photo wise) for one main reason.  Have you seen all the Samsung S4 commercials where a person is taking a picture, and someone else jumps in the way, and they can “edit” the image on the fly and remove the person that jumped in the way?  SmartShoot does the same thing!  It’s pretty awesome too.. it basically takes a series of pictures, and as you are looking to same any of the images, you can choose any “object” that is out of place, and the app will remove that object.

1. People

My main app among my list of “Top 5 Windows Phone Apps on Nokia Lumia 920” isn’t an app you have to install (much like OneNote), so don’t think I’m cheating here.  The best app on the phone to me is “People”, which is the repository of contacts and anyone you’re connected to in the networked world.  I give this app my number one spot because it is so central to the functionality of Windows Phone.  People will provide a list of all contacts, but the list comes from a combination of all social connections you link to your phone (Facebook, LinkedIn, Twitter), along with any directory\contacts you have linked to your email accounts (so my Exchange contacts appear, since my work email is linked in my phone).  Because of this integration, you can scroll through “People”, choose a person, and see a combination of all their data in one spot.. contact info, recent social network postings, shared images, etc.  Or, you can view “notifications” and scroll through the latest information that has been posted to the social networks listed above.. it’s almost like viewing Facebook, Twitter and LinkedIn all in one spot, and done so very well.  As stated earlier, I’m not a big user of social networks, and even I love this functionality.

So there you have it, the top 5 apps in Windows Phone that I think makes this device such an awesome one to use.  I do look forward to the app store gaining more momentum, and I do see it happening over time, but for anyone who tells you “there aren’t enough apps”, be sure that there may not be nearly as many as iOS or Android, but Windows Phone has plenty of quality apps nonetheless!

Monday, June 10, 2013

Book Review–The Violinist’s Thumb

The Violinist's Thumb: And Other Lost Tales of Love, War, and Genius, as Written by Our Genetic CodeThe Violinist's Thumb: And Other Lost Tales of Love, War, and Genius, as Written by Our Genetic Code by Sam Kean
My rating: 4 of 5 stars

This book was as well written as any book I ever read. It was incredibly researched and organized, and provided a compelling argument about genetic code, and its immense complexity. That being said, I wish I enjoyed this book more. At times, the scientific background provided about DNA and its meaning was well over my head, and I started to lose interest. Fortunately, only part of this book was scientific, the other parts were intriguing and insightful stories about genetics, or information about the early to modern day findings about DNA... Who studied it, why they did, and how many of them weren't appreciated for their efforts til decades later.

This book is very well written, but not always the "easiest" read. That being said, I am happy I took the time to power through it.

View all my reviews

Friday, May 31, 2013

Adding items to a drop down list in a ListView (or a GridView for that matter)

I’m in the process of creating a simple “product listing” in an ASP.NET website, just to show some products.. like t-shirts.. display a drop down list with the available sizes, and provide an “Add” button to add to a cart, much like this:

Capture

Even though it’s possible this application will barely get any usage within the next 6 months, and will probably display no more than 5 items at a time (it’s for internal company usage), I nonetheless decided I must make my code as efficient as possible.  I took to using a repeater control to iterate through an XmlDataSource and display my product data.  Within an hour, I had this working (hooray!).  Then, I added some form controls (buttons and drop down lists) with dummy data and quickly found that a repeater was a poor choice, as EVERY form control was submitted when the page performed a POST to the server (boo!). [Note: I really don’t understand why this happened.. I didn’t really find anything on this, or research it much, I just tried using a different control on a hunch, and it worked..]

Learning my lesson, I switched over to using a ListView control to instead display my data.  I was still able to use an XmlDataSource for my product info, and now clicking an “Add” button for a product added only that product, not submitting for every form control.  Now, all that was left to do was to bind actual data to my form controls, rather than use the pre-existing dummy data.  This was surprisingly difficult to do.

The task at hand was to edit the “product sizes” drop down list and provide appropriate values based as a comma delimited value in my XML file.  Namely, if the product was “Shirt 1”, and the sizes were “S,M,L”, then S, M and L should all be separate items in the drop down list.  The problem was, it was hard to find out *what* data was binding at any given time.

Fortunately, the solution was simple, I really think I was just not Googling properly.  To add items to the drop down list, I had to use the ItemDataBound event on my ListView control.  At that time, I had to check for my drop down list using the FindControls method, and then use the DataBinder.Eval Function to pull the data for that current row.  As I said, very simple, just not well documented (for the terms I was searching for at least ;)

Anywho, you read this far, the least I can do is give you a code sample as well.  Hope this helps!

            If e.Item.FindControl("ddlSize") IsNot Nothing Then
            'Get our dropdownlist
            Dim ddl As DropDownList = CType(e.Item.FindControl _
            ("ddlSize"), DropDownList)
    
            'Make sure we didn't already add items to this ctrl
            If ddl.Items.Count = 0 Then

                'get our sizes, which are stored in comma delimited format
                Dim sizes() As String = DataBinder.Eval _
                (e.Item.DataItem, "Sizes").ToString.Split(",")
               
                'add our items
                For Each s As String In sizes
                    ddl.Items.Add(New ListItem(s, s))
                Next

            End If
     End If

Thursday, May 30, 2013

Hikin’ (Ricketts Glen, PA)

The backstory: during the Winter of 2012, I followed a series of posts called “Offline”, in which a writer named Paul Miller from TheVerge.com left the Internet for a year and documented his life and times in the real world without having access to any resources or amenities provided by the cyberworld.  Late in 2012, Paul wrote a story about going hiking, and it struck a chord with me.  Paul and his buddy had to take a train, rent a car, and do all this crap just to get to the wilderness.  I can see mountains outside my window at home… I can be on that mountain in 15 minutes flat!  Paul’s article inspired me, and I decided that this Spring\Summer\Fall, I would start to enjoy the outdoors more.  This post is one such chronicle of this proposed adventure.

This past Monday was Memorial Day.  It was a beautiful mid-70’s day with a light, cool breeze.. a perfect day to have off of work.  What better way to honor those who served our country than to enjoy the land they worked so hard to protect.  As such, my cousin (Nick, an experienced hiker and all around learned man) and I made plans to visit a state park, Ricketts Glen.  I had heard how nice the park is, but had never visited it before.  The ride, in total, was about 50-60 minutes, including a visit to the local park office to acquire a trail map.

The trail map indicates that there are several trails available, but the most popular, as well as the most difficult, is the “Falls Trail”.  The trail is names such due to it’s number of waterfalls that you meander around.. 14 in total I believe.  Armed with this knowledge, our backpack full of hikin’ stuff, and ample quantities of water, we set foot.

(Photo courtesy of WikiPedia)

As you can see in the image, the trail is one large loop.  The southern-most point (indicated by the Shingle Cabin) contains the primary parking section to access the Falls trail, and you can visit either side of the trail first – at the Waters Meet mark to be particular about it.  Along the starting trail you are greeted with 3 separate waterfalls (Murray Reynolds, Sheldon Reynolds and Harrison Wright), just to “wet” your appetite (pun intended ;)

Arriving from this point, either side of the trail begins with an ascension up the various hills and rugged terrain, which at some points is rather steep.  Many stones are inlaid to provide as “steps” to go around the waterfalls, which is helpful, but there are many sections that are only 3 ft. wide or so, and stepping over that boundary will most certainly lead to injury due to the fall.  I mention this because I was shocked at how many children I saw attending the park later in the day.  It’s not that kid’s can’t walk this trail, but in all honesty, any parent looking to take their children should be aware.

For me, the highlight of the trip was the Ganoga waterfall.  While other waterfalls on the trail tend to average around 35 feet or so, this waterfall stands tall at 94 feet!  The hike to this waterfall makes the trip worthwhile, but the beauty of each waterfall is incredible.

In any case, Nick and myself actually entered from a different trail-point, and made the trek in roughly 2 hours.  As you can see below, the scenery is WELL worth it.  After our trip, I researched our park more and consistently saw it ranked as one of the top parks to visit in all of the Northeast!  I am not surprised however, having just visited the park, the views are breathtaking, and the trails are groomed considerably well.  In any case, if you haven’t yet visited the park and have the means to do so, I highly recommend you do.  And if you have visited the park before… well.. then I’m sure you understand :)

Finally, for more details on this park, check out Wikipedia.org

Enjoy the view!

PS - Incase you were curious on how to embed images like this in a blog post, I use SkyDrive, a FREE Microsoft Cloud product, and am also a member of the SkyDrive Insider's program. Should you be interested in becoming an insider, learn more about it here: http://sdrv.ms/V0buD7

Monday, May 20, 2013

Automatic Picture Backup on SkyDrive (subheading iCloud gets all the press)

Incase you didn't know, I'm a huge fan of SkyDrive, a Microsoft based product that let's you store and share document's in the cloud, giving you access to your files no matter where you are.  As such, I have been deemed a member of the SkyDrive Insider's program.  Should you be interested in becoming an insider, learn more about it here: http://sdrv.ms/V0buD7

Purchasing my Windows Phone

I took the leap a few weeks ago and switched my smart phone to a different model.  For several years now, I always used an iPhone.  In the beginning, it’s because it truly was the most innovative phone on the market, but in recent years it’s little more than average.  Meanwhile, I had often thought of getting a Windows Phone.. they do look sharp (note: as if that counts for anything?  Just last night some guy saw my phone and said “wow that’s a nice phone.”  The human in me said “thanks man” trying to sound cool and relaxed, the geek in me internally screamed thinking that I could have been holding a bright shiny yellow cardboard box, and the stranger wouldn’t know any different.  It’s just like buying wine because it has a pretty label, argh!), the OS is presumably polished, and to be honest, nary a negative word is ever said about the Windows Phone.  Therefore, this past week I went out and bought myself a Nokia Lumia 920. 

Of course, what makes a phone a good phone are the features, and in particular the features that set it apart – something that Michael E. Porter would refer to as a Competitive Advantage.  The phone is exactly as advertised… the camera is very nice – they even expose the lens to developer API’s, giving a lot of “app” functionality and option’s, to the point that you can find a number of apps that are specific to taking pictures and video.. pretty cool.  The OS is polished (as referenced above in my presumptions), it flows really really nicely, and the live tiles feature is very cool.  I do have 2 minor complaints however.  1, I wish you could change “some” of the tiles, more-so than just the size of the tile.  I wish I could make my “phone” tile small, but make it a different color, so it would still jump out at me when scrolling through my home screen.  The other feature I’d like to see is some sort of “lock” on the tiles.  As you constantly re-tool and swap live tiles with the phone, all tiles slide up and down, meaning you have to constantly re-learn where some tiles are as you edit your home screen.  These features are nit-picky and wouldn’t prevent me from purchasing this phone, but they are something I’d be excited to see.

Social Media and SkyDrive Integration

Now, there are 2 features that I absolutely love about my phone: it’s integration with social media and with SkyDrive cloud storage.  Windows Phone has a settings section called “Email + Accounts”, where you can input your account information for FaceBook, LinkedIn and Twitter (for more details, check out http://www.windowsphone.com/en-US/how-to/wp8/people/social-networking).  Once inserted, all your friends\contacts\followers data is imported into your “People” (generic term for contacts, just didn’t want to re-use that term here).  When browsing People, it provides a one-stop-shop to send someone an email, SMS message, FaceBook chat, write on their wall, or even tweet them.  FaceBook notifications are shared seamlessly, and all new posted images on Twitter show in a social “camera roll” within your Photo’s section.  It really is a novel concept, as the phone almost “updates” itself.  Soon you’ll see yourself checking your phone for social updates in the same fashion as you would find yourself checking your phone for email.

And last, but certainly not least, is my other favorite setting, the integrated storage with SkyDrive.  I know I put a “disclaimer” up above about my SkyDrive Insider status.. trust me.. this feature is great because of how well it works.  In your “Email + Accounts” section, you can provide a Windows Live ID and password.  Once done, it will sync any “outlook.com” email that you have through that service, but it will also “silently” integrate with your SkyDrive storage.  In doing so, all photo’s and video’s you take with your phone are automatically backed up on SkyDrive.  These aren’t stored in some proprietary backup file like some “other iService”, instead each individual file is available like a normal “jpeg” or video file.  You can download the images one\some\all when necessary from any PC whenever you have Internet access.  Additionally, when you store Office documents in your SkyDrive (Word, Excel, OneNote, or PowerPoint in particular), those files also appear for edit\review in the “Office” Hub, where you have native file support for Office files.  There isn’t any special downloading, it just sync’s on the fly because of how you added your account in the “Email + Accounts” setting.  It works as quietly and “seamlessly” (not to overuse that term..) as you would hope it would.  It doesn’t prompt you, or scream about how or what it’s doing, it just writes and syncs files, waiting for that time that you decide to drop your phone in the toilet, voiding your warranty and causing you to get a new phone.. but at least you won’t have to resync all your data on your new Windows Phone (because I guarantee you go and get another one), since all that data is in the Cloud!

Some Synced Pictures from SkyDrive

Thursday, May 2, 2013

An Introduction to Querying and Creating Report Subscriptions using the ReportingService2010 Web Service and SharePoint

I recently found the need to create a custom reporting service subscription manager for my workplace.  We currently employ SQL Server Reporting Services to generate and maintain our reports for our end users, and after a little digging around I uncovered the ReportingService2010 web services exposed by SQL SSRS - http://msdn.microsoft.com/en-us/library/reportservice2010.reportingservice2010.aspx.  I wasn't aware of it at the time, but the way Microsoft SharePoint and so many of these other Microsoft Services interact is all via web services.  When SharePoint provides links to manage shared schedules or generate reports, many of the functions they provide access to are just web services enabled by the service you are interacting with.  This means that you can access the same data and functions that is provided "out of the box" by many software packages, if you're willing to slap on your own UI and learn how to interact with the appropriate API's.  This post is to discuss the latter half of that statement and introduce you to working with the ReportingService2010 SOAP enabled web services.

Let's start here, the ReportingService2010 Class embodies many of the methods and properties used to work with both Reporting Services Native Mode as well as SharePoint Integrated Mode.  The examples I'll provide below will be aimed towards a SharePoint Implementation, but in browsing the MSDN documentation, you'll see that many of the methods are the same, the differences are typically in what parameter data you may be passing back and forth.

So let's get started.  Before you do anything else to work with your Reporting Service API's, in your Visual Studio Solution generate a web service reference to your SSRS server.  The format to connect to your service should be along the lines of: http://_Server_Name_/ReportServer/ReportService2010.asmx?wsdl.  Once created, add your namespace to your Using\Imports statement on your class files.

Now that that's done, let's look at some of the common methods you may need to use.  Anytime you need to interact with your reporting server, you'll need to authenticate.  An easy way to do so is by using the following:

Dim rs As New ReportingService2010
rs.Credentials = System.Net.CredentialCache.DefaultCredentials

What will this do?  At runtime, the credentials will take on the credentials of the user running the application.  If this is a website for example, this will be the service account assigned to the application pool in IIS.  However, if you enable identity impersonation (http://msdn.microsoft.com/en-us/library/aa292118(v=vs.71).aspx), then the DefaultCredentials will be of the user accessing the website.

This can be a very handy feature, but in my implementation, I also found the need to create new subscriptions, or edit\delete existing subscriptions.  For something like this, unless all of your users are "power" users in SharePoint (which I assume they're not), you can also specify a particular user account to run under.  You can do so by creating a new NetworkCredential object, like so:

rs.Credentials = New System.Net.NetworkCredential("<UserName>", "<Password>", "<DOMAIN>")

This feature was the most important feature I had worked with, because there are times that you *need* to perform actions under a higher privileged account (like create or delete subscriptions), and there are times that you just need to read data for the current user.  Keep this concept in mind as you begin to interact with your SSRS implementation.

Note: Herein, any reference to the ReportService2010 object will be referenced as if it has been “defined” as rs.

SSRS - Working with Reports, Subscriptions and Schedules

Let's start simple.  Let's say you want to programmatically access a report.  Each Report is referred to as a "CatalogItem" object (http://msdn.microsoft.com/en-us/library/reportservice2010.catalogitem.aspx).  To get your reports, just call the ListChildren method of your ReportingService2010 object, providing the URL to the SharePoint library that contains your items.  Here's such an example:
       
Dim r As List(Of CatalogItem) = rs.ListChildren("http://mySharePointSite.com/Report Library", False).ToList()

The first parameter is the URL where your RDL reports are located, the second boolean parameter defines whether or not the result set should return recursive items.  Otherwise, it's as simple as that.  Now you'll have a List of reports where you can determine when the item was created, it's name, description.. all that good stuff. 

Chances are you grabbed that line of code, pasted it into your IDE and ran it, and hopefully it worked just fine for you.  However, I want to make sure you are aware that the ListChildren method will return results based on the context of the Credentials in your ReportService2010 object.  So if user's don't have permissions to an Library, or an object in that Library, they will not receive results for the ListChildren call.

Let's say you want to have access to what Shared Schedules you created on your site, here you can receive a List of all Schedules currently stored using the ListSchedules method:

Dim schedules As List(Of Schedule) = rs.ListSchedules("http://mySharePointSite.com").ToList()

Notice I didn't specify a particular report library or anything like that.  Since schedules are stored at the site level, and not within a particular library or anything like that, you only need to specify the location of your SharePoint site where you defined your schedules. 

ListSchedules returns Schedule objects, defined here: http://msdn.microsoft.com/en-us/library/reportservice2010.schedule.aspx. The Schedule object offer's a number of very helpful properties including the Last Run Time, the Next Run Time and the Description of the schedule.  However, the most important property exposed here is the ScheduleID, a GUID based value that allows you to reuse the schedule at a later date.  More on this value later.

Let's say for a moment that we want to determine what parameters a report can accept.  This is done with the GetItemParameters(http://msdn.microsoft.com/en-us/library/reportservice2010.reportingservice2010.getitemparameters.aspx) method, as shown below.  This method will return an array of ItemParameter objects (http://msdn.microsoft.com/en-us/library/reportservice2010.itemparameter.aspx) and contains pertinent information including the display text for the parameter, the prompt text for the parameter, default values (if any) and *acceptable values* (if any)... which is very important when creating new subscriptions using parameters, as the SOAP API's will thrown an exception if a parameter is used with a value that is not within this list of values.  To call this method, you just need to pass the report path for your report, including the file name with the rdl extension.  You also have the option to specify a "historical" report (incase you want to check a report snapshot), a boolean based "ForRendering" parameter, an array of ParameterValues that can be validated against the report upon calling the method, and a DataSourceCredentials object that can be used to validate any query based parameters.  However, if you simply wanted to just get the Parameters for a report, the following code will do so for you:

Dim reportPath As String = "http://mySharePointSite.com/Report Library/SomeReport.rdl"
Dim forRendering As Boolean = True
Dim historyID As String = Nothing
Dim values As ParameterValue() = Nothing
Dim credentials As DataSourceCredentials() = Nothing
    
Dim parameters As ItemParameter() = rs.GetItemParameters(reportPath, historyID, forRendering, values, credentials)

OK, we can call SharePoint and return some report names and shared schedule information, which is cool, but let's take it a step further.  My need to work with these API's was to enable some usability with creating and editing subscriptions.  We can access subscriptions using the ListSubscriptions method, which only requires the path to your report library, along with the name of the report you are requesting access for.  ListSubscriptions returns a dataset of Subscription objects, which is defined in detail here - http://msdn.microsoft.com/en-us/library/reportservice2010.subscription.aspx  The most important property exposed here is the SubscriptionID.  Querying your SSRS server using the SOAP API's will require a subscriptionID in most cases, and further down in this post you'll see where\when this comes in handy. If you perform the following, you'll get a List of all subscriptions for the report *based on the user context* - so if you want all subscriptions, use a priveleged account.  Otherwise, the subscriptions will be based on who is running the command:

Dim subs As List(Of Subscription) = rs.ListSubscriptions("http://mySharePointSite.com/Report Library/SomeReport.rdl").ToList()

At this point, our List will contain Subscription objects, but what about the data they contain?  The Subscription object contains data about who the Owner is, or the Path of where the Report file is located, but that isn't too insightful.  If we want to learn more about the specifics of a Subscription, such as who is receiving report data, what its current state is, or who the owner is, among a plethora of other details, we use the GetSubscriptionProperties method.  Let's start simple, I'll give you some code to look at, and then explain what this all is.

Dim subID As String = "<Some Sub ID>"
Dim subExtensionSettings As ExtensionSettings
Dim subDescription As String = ""
Dim subActiveState As ActiveState
Dim subStatus As String = ""
Dim subEventType As String = ""
Dim subMatchData As String = ""
Dim subParams() As ParameterValue

Dim subscriptionOwner as String = rs.GetSubscriptionProperties(subID, subExtensionSettings, subDescription, subActiveState, subStatus, subEventType, subMatchData, subParams)
   
The GetSubscriptionProperties method, which is defined here http://msdn.microsoft.com/en-us/library/reportservice2010.reportingservice2010.getsubscriptionproperties.aspx, returns a string value indicating who the current *owner* is for the provided Subscription.  Consider the owner as who the report runs "as" (which was a handy concept for me, as many of my subscriptions do take into consideration who the user is to provide certain data).  As far as the other parameters are concerned, these are all output parameters populated based on the result of the API call.  So in reality, all you need to retrieve information here is just the SubscriptionID, the rest gets populated.

The true knowledge of the Subscription information is contained within these returned values, of course, so let's walk through them.

subExtentionSettings is an ExtensionSettings object (http://msdn.microsoft.com/en-us/library/reportservice2010.extensionsettings.aspx), which is rather boring as it only contains an array of ParameterValues and an Extension string property that defines what the report subscription is.  As an example, for email based reports, Extension is set to "Report Server Email".  ParameterValues is a collection of key\value items that contains the basic information about a subscription, including the following:

- TO
- CC
- BCC
- ReplyTo
- Subject
- Comment
- Priority (Low, Normal, High)
- IncludeLink (Boolean)
- IncludeReport (Boolean)
- RenderFormat (The report file type that is attached to the email.   Possible values are WORD, PDF, ATOM, RPL, IMAGE, CSV, EXCELOPENXML, HTML4.0, WORKOPENXML, MHTML, EXCEL, and XML)

subDescription is just a string typed description of the subscription, such as "Send e-mail to someuser@mycompany.org".

subActiveState is an ActiveState object(http://msdn.microsoft.com/en-us/library/reportservice2010.activestate.aspx).  As indicated in MSDN, this object "Represents information about the active state of a subscription. An ActiveState object is returned by methods that query subscription properties.  The active state of a subscription indicates whether a subscription is currently active and valid. If there is a problem with the subscription, the active state of a subscription can be queried programmatically to determine the cause of the problem. More than one error condition can cause a subscription to be inactive. Subscriptions that are inactive are not processed by the report server until the cause of the error is resolved.".  When creating a new subscription, an object of this type needs to be passed, but it really is to determine the current "state" of a subscription when a subscription fails for some reason, not so much to provide input parameters.

subStatus represents the most recent status of the subscription.  For example, a successful emailed subscription will read "Mail sent to someuser@mycompany.org".

subEventType represents the type of subscription you are querying. There are 2 main types, a Timed Subscription, and a Data Driven Subscription.  The EventType parameter will indicate what type of subscription this is.

subMatchData is a string based parameter, but it will provide 2 different types of values, either a GUID or an XML string.  The difference here is whether or not you are using a shared schedule for this subscription.  If you are, then the GUID value provided is the ScheduleID of the Shared Schedule (meaning you can use this to match up with a ScheduleID from the ListSchedules method discussed earlier).  If you receive XML, it is because the subscription is using a "custom" schedule, and the XML defines what days of the week the report "event" should occur, along with what time.

subParams is an array of ParameterValues (much like those defined above in our ActiveState object).  These values however are the input values that are used to generate a report.  So when you are interacting with a report, and you are requested for a start date, or an end date, or a user ID, or a customer number, etc. these values are all found here.  There is one exception to this rule, and that is default values.  If a report can accept "default" values, and the value for the parameter was chosen as default when the report is created, then this value will not exist in the ParameterValues array, as it is simply not stored.  Let me repeat this, the value isnt stored as "NULL" or "BLANK" or "DEFAULT", it is simply *not there*.  If you want to retrieve a list of available parameters for a report, you would use the GetItemParameters method (discussed above).

Creating A New Subscription

OK, with all of the knowledge attained above, the last item I'll cover is creating a new subscription, which basically uses a combination of the properties and objects defined above.

First, your ReportingService2010 credentials object must be a privileged account to create a subscription.  In my case, I defined a "service account" on my domain to perform such actions, and allow this service account to create subscriptions on behalf of a user.  However, the creator of a subscription is also the default *owner* of the subscription, and as we discussed earlier, the owner is who the report runs *as*.  Keep this in mind, as you may want to alter who the owner is after creating the subscription (which is simple!).

Creating a subscription is simple, all you need is the correct data to generate the subscription in your system, namely the report your creating a subscription for, who it's to be emailed to, the attachment type, a description, an event type, the schedule to send the report, and the parameters for the report (all this sound familiar from above?)

My code to generate a new subscription is similar to the following...

'DONT COPY AND PASTE THIS CODE, IT WONT WORK!  Keep reading below to understand why and what you need to do..
Dim reportPath As String = "http://mySharePointSite.com/Report Library/SomeReport.rdl"
Dim newSubExtensionSettings As ExtensionSettings = GetEmailSettings()
Dim newSubDescription As String = "Send e-mail to someuser@mycompany.org"
Dim subActiveState As New ActiveState
Dim subStatus As String = "New Subscription"
Dim newSubEventType As String = "TimedSubscription"
Dim newSubMatchData As String = "<Some Shared ScheduleID>"
Dim newSubParams() As ParameterValue = GetReportParameters()

Dim subscriptionID As String = rs.CreateSubscription(reportPath, newSubExtensionSettings, newSubDescription, newSubEventType, newSubMatchData, newSubParams)

As you can see in the comment, that code wont work above for 2 reasons, and it's really because I'm avoiding code bloat here.  newSubExtensions is looking to call a custom method called GetEmailSettings.  All this does is create a new ExtensionSettings object, and populate the ParameterValue array with the appropriate data.  What is the *appropriate* data?  Scroll up above, it's a list of TO, CC, Subject, etc. as defined above.  These are just key\value pairs for the subscription, nothing more.

newSubMatchData should pass either formatted XML or a ScheduleID of a shared schedule on your SharePoint site.  For my application, I just created shared schedules and ensured that all users only had the ability to use a shared schedule and NOT any custom subscription times, just to make maintenance periods that much easier.

Finally, newSubParams calls GetReportParameters, returning an array of ParameterValues.  Much like the ExtensionSettings, you just need to generate some key\value data that aligns with the acceptable parameters of your report (found by using the GetItemParameters method, described above.)  So my custom GetReportParameters method simply has some logic to iterate through my form, grab the appropriate data, and generate this array of values.

Once you have all this data populated, and you call the CreateSubscription method, SSRS will attempt to generate a subscription.  If any parameter values are incorrect, or if any other data seems invalid, you'll get an Exception.  If it works, a string is returned, which is your SubscriptionID, and it'll look like a GUID.

The last thing you may want to do (I did it, but it's theoretically optional) is to update the subscription owner, for reasons defined above.  Doing so is very simple, just call the ChangeSubscriptionOwner method, like shown here:

Dim subID As String
Dim ownerName as String

rs.ChangeSubscriptionOwner(subID, ownerName)
   
Told you it was simple!

Updating An Existing Subscription

At the present time, you can't update a subscription (unless I missed it somewhere in the documentation - http://msdn.microsoft.com/en-us/library/ee640242.aspx).  So, when I need to update a subscription, I just delete the current subscription, and then recreate a new one.  Deleting a subscription is as simple as executing the line below:

rs.DeleteSubscription(currSubID)
   
That's everything in a nutshell, hopefully this gives you a solid anchor point to develop your own custom report subscription application... hope this helps!

Thursday, April 18, 2013

How to encrypt app settings in a web.config

In a web application I recently developed, I found the need to store credentials for a rather powerful service account in my web.config.  The reason being, I needed to authenticate as that service account user at times, and use normal user credentials at others.  I was able to use the service account details without issue, but incase we ever found the need to update the account name or password, I wanted to make this value part of the web.config, but also have the means to encrypt this value to shield it from prying eyes.  Fortunately, using some web.config transforms and the aspnet_regiis –pef command option, this isn’t all too difficult, and we can have a perfectly normal web.config, but encrypt just one section of the web.config to hide sensitive data.

Step 1, Create a new web.config section

In your web.config, within the configuration\configSections area, add the following XML:

<section name="secureAppSettings" type="System.Configuration.NameValueSectionHandler, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

This XML will allow us to create a new section called secureAppSettings within our config.  You can call this whatever you want of course, but me… I like secureAppSettings.

Still within your config file, after your <appSettings> section, create a new section called secureAppSettings, and within this section add your key\value pairs, like so:

<secureAppSettings>
  <add key="testkey" value="This is a value in secureAppSettings testkey"/>
</secureAppSettings>

Step 2, reference your value’s in your code

Now that you created your values, you reference them in your application *almost* like normal.  Rather than referencing your AppSettings object of the ConfigurationManager class, you need to reference the “secureAppSettings” section instead.  This is simple.. but a minor change nonetheless.  So, find where your code is looking to reference our new secure values and reference the secureAppSettings key like follows:

Dim myVal as String = ConfigurationManager.GetSection("secureAppSettings")("testkey").ToString

Do you see the difference?  Here, we need to use the “GetSection” method, and then specify our “secureAppSettings” section.  Then, we reference our “testkey” value.  As I said, it’s a minor change.  Also take note, we do not need to do anything different to worry about the encryption\decryption of the web.config value, as the .NET Framework will handle that for us.  We simply need to reference the value, the .NET Framework will handle the rest.

Step 3, Encrypt Your Config Section

Here’s the fun part.  Publish your application, so you have a full config file.  (Personally, I like to publish to a local directory on my PC so I can push all files to my staging\production server’s manually when possible).  Once you publish the application, navigate to the publish directory and take a peek at the web.config.  How does it look?  Like normal, right?  Take this file and copy it to your web server, then remote into your web server and open a command prompt (run as admin just to be safe).  The encrypted values are generated based on the server’s machine key, so executing these command’s on a PC that isn’t your web server could cause unintended results.

Once within a cmd prompt, execute the following 2 command’s

1.) cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319

2.) aspnet_regiis -pef "secureAppSettings" "E:\YourPhysicalPathToTheFileLocation" -prov DataProtectionConfigurationProvider

For your physical path to the file location in the 2nd command, you do not need to specify the file name, simply the directory it resides in.  So it would be “E:\mydir\mysubdir”, NOT “E:\mydir\mysubdir\web.config”. Once you complete both commands, take a look at your config now.  You should see something similar to the following:

<secureAppSettings configProtectionProvider="DataProtectionConfigurationProvider">
  <EncryptedData>
    <CipherData>
      <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAxFAcBHLMb0uk5ES0SYgO2AQAAAACAAAAAAA………………………..2fZwOKP8VFg7OW2eMYFnq86TbUhB92EOQk0DhPqxDaA0pnp7MwRq2YR5CjmVAOFAAAAAxzUbeL1Fuij0DFEe0Cb7KEa92/</CipherValue>
    </CipherData>
  </EncryptedData>
</secureAppSettings>

Check it out!  Now, your secureAppSettings config values are encrypted!  As stated earlier, there’s no need to reference these values any differently in your code, other than specifying the secureAppSettings section.

Step 4, Merging these values back within your code

As I stated earlier, I needed to encrypt a username and password, just incase the value needs to change later on.  So in my scenario, I only need to document this process and generate my encrypted values once.  Then, if I ever need to publish a new build, I can still promote the same config values, and only worry about updating these username\password values if they ever change.  To handle this, I just placed my secureAppSettings in a web.config transform.  To do so, within Visual Studio, open your Web.Release.config transform file.  In the appropriate section (for me, this was below connectionStrings and above system.web), place your encrypted values using xdt transform notation:

<secureAppSettings configProtectionProvider="DataProtectionConfigurationProvider" xdt:Transform="SetAttributes">
<add xdt:Transform="RemoveAll" />

  <EncryptedData xdt:Transform="Insert">
    <CipherData>
      <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAxFAcBHLMb0uk5ES0SYgO2AQAAAACAAAAAAA………………………..2fZwOKP8VFg7OW2eMYFnq86TbUhB92EOQk0DhPqxDaA0pnp7MwRq2YR5CjmVAOFAAAAAxzUbeL1Fuij0DFEe0Cb7KEa92/</CipherValue>
    </CipherData>
  </EncryptedData>
</secureAppSettings>

The code above does a few things.

1. The SetAttributes on the secureAppSettings node causes the transform to add the configProtectionProvider attribute.

2. The RemoveAll transform removes any non-encrypted key\value pairs you may have in your web.config prior to performing a publish.  This means that your web.config during local debugging can still have your clear text key\value pairs, but they’ll get removed when you perform your publish.

3. the Insert transform will cause the EncryptedData, CipherData and CipherValue nodes to copy into your transform.

Step 4b – Updating your encrypted values

Should you have the need to recreate a clear text version of your web.config again, so you can update your values and re-encrypt them, just create a new publish profile within Visual Studio that publishes to a directory, but does NOT use your web.release.config transform.  This way, you can publish your config to a local directory and repeat the steps listed above.

Hope this helps!

Wednesday, April 17, 2013

System.Web.Services.Protocols.SoapException: Default value or value provided for the report parameter '<paramName>' is not a valid value

SharePoint has an odd limitation, with reporting services, user's don’t have access to properly subscribe to their own reports.  If you provide users with the ability to subscribe, they must also have access to edit subscriptions, and that means ALL subscriptions, which doesn't bode well, because users will just hate that.

So I took to creating a custom web form that allows users to edit and maintain their own subscriptions.  The form uses the SQL Reporting Services exposed web services via the ReportService2010 class (http://msdn.microsoft.com/en-us/library/reportservice2010.aspx), and uses these methods to read all report subscriptions in for a user, available parameter's for a report, etc.  I plan on doing a separate blog post on this because, frankly, I think it's cool.

Anyway, I was about to launch my afforementioned masterpiece when I receive an error in attempting to subscribe to a report: Default value or value provided for the report parameter '<paramName>' is not a valid value

This was all very confusing, because all along I have been creating subscriptions for myself and others.  The parameter values I am pumping into the report subscription are all supplied by the reportservice method GetItemParameters, which has a ValidValues property that lists what the valid values are.  And sure enough, for my parameter, I was supplying a Valid Value!

After quite a bit of debugging, tweaking some code to test some scenario's and cursing Microsoft, I found out that.. as usual.. it was an end user (me) error.  It's kind of an oddball scenario, but I imagine it could happen to others, which is why I am writing this blog post, which presumably is why you are reading it...

The report parameter that was failing for me was a user drop down list, which is generated based on who is attemping to create the report subscription.  So User A will see different values than User B.  When generating the parameter values for the report subscription, I was using the following code:

'Note, for this web form, Impersonate is set to TRUE
Dim rs As New ReportingService2010
rs.Credentials = System.Net.CredentialCache.DefaultCredentials
……
parameters = rs.GetItemParameters(“A Plethora of Parameters”)

The important line of code is the 2nd one shown above, setting the Credentials to DefaultCredentials.  When this is used to authenticate with the reporting web service, the user's credentials are passed, meaning User A or User B are sent to the server.  The appropriate values are then returned for the report parameters, so they vary properly depending on if the user is User A or User B... all as expected.

With me so far?  OK, Good...

My issue was when I was creating the report, not generating the parameter items.  To give every user the ability to create a report, without granting them access to view\edit subscriptions within SharePoint, I was executing the CreateSubscription method underneath the context of a service account, NOT as User A or User B.  So in the end, my code looked similar to:

Dim rs As New ReportingService2010
rs.Credentials = New System.Net.NetworkCredential _ ("serviceAcctName", "password", "Domain")
……
subscriptionID = rs.CreateSubscription("A plethora of parameters")

What was the issue? 

When the CreateSubscription method was executing, it was executing under the context of my "serviceAcctName" user, not as User A or User B.  This means that, even though I was passing valid values for my parameter for the user, these weren't a valid value for the "serviceAcctName" user, meaing that the exception was accurate.

In the end, I was able to tweak my back end logic that was generating the custom drop down list values to include every value possible for the "serviceAcctName" user, so no matter what user would be using my subscription manager, it would be a valid value for my service account.

I don't know how many other's will run into this particular scenario, but if you're one of them, I hope this helps!

Friday, April 5, 2013

Why Use An IDE?

Artists have a quote that says "A blank canvas is an open opportunity to create whatever your imagination can stir to life". All artists begin with a medium of their choice, and use that medium to bring together their creation. Some artists use paint, some stone, some sand, and some even resort to using natural elements such as ice and snow. As such, all successful artists have a mastery of their tools to maximize their skillset.

I often tell developer’s in the making that using ASP.NET, Visual C# and Visual Basic is a specialized skillset, as the programmer not only develops code to control the application, but design's the interface in which the user uses the program a well. This is an important concept, as the misplacement of a button, or inadvertently hiding certain options can cause an immense amount of disdain from your end-users. It is impossible to overstate how important a toolset is to programmers. Much like artists needs to understand and use their tools appropriately, programmers must do the same. Failure to do so will cause over-complicated code, causing projects to run over time and over budget. Using toolsets properly will only serve to enhance the programmers ability to create enterprise-level applications that provide value to end-users and development teams alike. 

The most important tool a developer will ever use in your programming career is the Integrated Development Environment (IDE). There are many different IDE's available to programmers, but the choice of a programming language depends on the hardware you intend to run your applications. Much in the same vein, the IDE you choose is dependent on the language you want to program with. Some common examples include IBM's Eclipse which support's Java natively, Anjuta which supports a number of Object Oriented languages but runs on a Linux computer, or SharpDevelop, a free and popular IDE that support a number of languages, and is supported by an open source community of software developers. When it comes to programming with Visual C# however, one of the best IDE's available (if not the best) is Visual Studio.

Visual Studio natively supports .NET languages, including C#, VB.NET, ASP.NET, and F#, and supports a wide number of community sourced plugins as well. Visual Studio also has a rich history with programmers, as it's first version of a development platform was made available to users in 1995! Microsoft has continued to upgrade and enhance the tools available for programmers as they have developed their programming languages as well. More recently, as the .NET initiative has taken flight, Microsoft has released a version of Visual Studio to match releases of it's .NET Framework, which has been every 2-3 years or so. Why do this? Simple, as new programming features and upgrades are made available to the .NET Framework, Visual Studio's latest tools will reflect those changes and features, allowing programmers to upgrade both existing applications and new applications to use said features.

You may not be aware, but the .NET SDK (Software Development Toolkit) is available through Microsoft's website. Using this SDK, you can install all features necessary to compile a defined program, review any error's, resolve them, and re-compile to create your very own executable file. Best of all, this SDK is completely free! This means you can actually write programs in any old-fashioned text editor (such as notepad), and run the commands necessary to compile those files into an application.

So you may be asking yourself, why wouldn't we do this? Well, the .NET SDK provides the capabilities listed above, but it is very raw, basic, and obtuse. With Visual Studio however, the programmer has the capability to perform the functions listed above, but is also provided several benefits including the following (for a full list of the options available, visit http://www.microsoft.com/visualstudio/eng/products/compare:

  • IntelliSense (real-time object exploration)
  • Code Formatting
  • Debugging and diagnostics
  • Deployment Options and Code Refactoring
  • Testing Tools
  • Development Platform Support
  • Architecture and Modeling
  • Lab Management
  • Team Collaboration Tools
  • Integration with other Microsoft products (such as SQL Server Databases, or SharePoint powered Internet websites)

Needless to say, there are enough features in Visual Studio to teach an entire course! As you can see, however, an IDE is so much more than code formatting, it is an entire management tool for a programmer to write code, create files, store information, debug an application, write test cases for the program, create documentation and publish, all in one spot.

Wednesday, April 3, 2013

Human’s are so funny (and odd and not like web applications in any way)

We have a kitchen area where I work.  It has a few refrigerator's, a stove, some free coffee, Tylenol, a bunch of empty cabinets and a sink.  It's pretty nice though, as our building is only a few years old.  There are 2 cylindrical receptacles in the countertop next to the sink, and there's a small note between the 2 of them that reads "Recyclable's Only", and underneath that text there are 2 arrows, one for aluminum and the other for plastic.  Wouldn't you know it, no matter how many gripes people may have, people in the building still use those receptacles to throw away normal trash, out of convenience.  The typical garbage thrown in there are empty coffee creamer containers, some napkins, or a Styrofoam cup (ironically in a recyclable container, as Styrofoam cups and cockroaches will undoubtedly live to the end of time).  There are also some trash bins against the wall, no more than 3 feet away from a person at the sink, but those are "behind" them.

In an experiment recently, I took a small trashcan and placed it under the sink (there is no cabinetry underneath, so it was visible).  No signs were posted, nothing was said, the trashcan was just placed there.  Wouldn't you know it, people started using the recycling and trash receptacles properly?  Oddly enough, someone else stole (yes, I'm accusing someone of theft!) the small trashcan about 2 months later, and the all-purpose recycling and garbage dumping started once again, with people just using the receptacles for whatever their refuse needs were at the moment.

This goes to show 3 things.  1, my fellow employees apparently don't care about the environment, 2, I enjoy using co-workers for pointless experimentation, and 3, human's are funny and fickle creatures who tend to take the path of least resistance.

I read a book recently by Dan Ariely (http://danariely.com/), a behavioral economist who studies people, and the more he learns about people the more he realizes how little he knows about people.  In a talk once, he told the audience that asking a person to opt-out of something occurs much less frequently than having people opt-in.  The example he provides is the amount of organ donor's in certain European countries.  The difference between the high and low rate of organ donor's has little to do with morality, upbringing, subsidies or any other influences.  It's only because the countries with the larger\largest organ donation have a form with a box stating "check this box if you do NOT want to donate your organ's after you meet your untimely demise" (yes, I paraphrased).  But do you understand the difference here?  Asking user's on a web form to opt-in to an email campaign is much different than asking them to opt-out.  Furthermore, the implication of the result is HUGE!  A person who has to opt-in for an email message is probably much more interested in your monthly email discussing widgets, rather than the person who happened to sign up for it "by default".

Whenever I'm teaching programming to software developer trainee's, I always tell them "the computer does what you tell it to".  When a trainee creates a loop in their program, or if a font color changes "randomly", I remind them of that phrase, and tell them that it's a bug.  They may not have intended for something to happen (hence it being a bug), but the computer does what it is TOLD to do.  It doesn't ask any questions (unless you tell it to ;), it just runs the code and that's that.  Human beings are so much more complex than that, it's always an interesting world to be between, programming a web application one minute and deigning a user interface where I'm guessing a user will or won't check a checkbox the next.  Such is life...