Thursday, December 13, 2012

Rotating Quotes on my Intranet via ASP.NET

I had a few hours to perform some cleanup activities, and I wanted to mix in something a little fun for my Intranet.  Where I work, some business\leadership writers are often cited and\or celebrated, to the point that our conference rooms have been named the "Godin Room", "Buckingham Room" or "Collins Room", and in each room a few samples of their work.  I thought it would be fitting to take quotes from some of these leaders, place them on an image, and rotate an image periodically on my homepage.  This ended up being so stupidly simple, I wanted to post some code to do it as well.

Step 1 - Create your images

As indicated above, create the images you want to rotate.  For me, I found a plethora of quotes, and placed a quote on an image that was a picture of a room, hallway, or somewhere else in our building*.  In the end, I wound up with 27 different images, looking similar to the following.



 


The key item here is that you probably want every image to be the same size.  In the end, I had a 300x200 jpg, and then added some whitespace below it to add a quote, so when all was said and done, each image is 300x283. 

Finally, you also want to name your images consistently.  So name the images 01.jpg, 02.jpg... 24.jpg.

Step 2 - Write some code

In principle, all I wanted was to show an image.  I didn't it to randomly load each time, because some of my users are mobile users, and I didnt want to eat up useless bandwidth.  Plus, I didn't want to randomly load an image periodically.. if I made 27 of these things, I wanted them to cycle through appropriately. In the end, all I did was:
  • Create a text file that stores the value of the last image that was shown
  • Store an image file name in server cache that expires
  • Set a parameter that indicates what the "last" image is in our rotation
Again, this is stupidly simple.  In an ASP.NET project, create an images directory off of your root, and store all your images in there.  Next, create a new page.. or use default.aspx.  You don't need ANYTHING on the aspx page, so go right to the code behind.

In the code behind, I used the following code in the page_load




As stated above, all this code is doing is reading the current value of an http cached item.  If that value isn't null, then the item hasnt expired yet.  If it is null, We read a line in a text file to determine what the "last" image was that was displayed.  We then increment that number by 1, add that value to our cache, update our text file to reflect the current files image name, and write the image out to the page.  The last line here is of the most importance though.. we also set cache of the response object to none... this way, the users web browser doesn't cache the result.  If it does so, then the image would never update on their PC, unless they performed a hard refresh or cleared out their browsers temporary items.

Thirdly, in your web root, create a text file called "lastimg.txt".  In that file, enter the term "01", save and close the file.  Now, when you run the project, the application thinks that the last image displayed to a user via cache was 01.
Now, you might be thinking.. do I specify a cache timeout?  Or what about a jpeg extension? Or how do I know when I got to my last image!?  Have no fear, the web.config is here.  Add these items to your web.config:

    <add key="maxFile" value="27"/>
    <add key="fileType" value="jpg"/>
    <add key="expTimeMinutes" value="60"/>

These items are already included in the logic from the code displayed above.  MaxFile is the last file that you have in your rotation (so if you only have 12 images, this value would be 12.. and so on).  FileType is your image file type, all mine were jpg, so I stored this value as such.  expTimeMinutes is the amount of time an image will be cached for, before rotating to the next item.

Step 3 - Host It!

Go ahead and run\debug your application.  When you see it working, go ahead and deploy this piece of modern artistry.  Just make sure that the user the application is running as has write access to the lastimg.txt file, so it can update it as it runs.

Once deployed, in SharePoint, create a new Image Web Part.  In the properties, for the Image link, just link to your application's <whatever_you_called_it>.aspx page, and click OK.  Now, your images will display in your Intranet site!

*Someone in our building took hi-res photo's of our boardroom, front lobby, etc.  I took these images, popped up in PhotoShop, and used one\two of the filters to give the pictures a unique effect, such as an oil painting feel, or a colored pencil drawing.

The permissions granted to user are insufficient for performing this operation. (rsAccessDenied)

With my SharePoint 2010 launch looming, I rolled my site out to some "select" users to give the site some gas, revv up the engines, and hopefully not have it come to a screeching halt.  Almost immediately, my users encountered an unusual error when attempting to execute an SSRS report we converted - "The permissions granted to user <user> are insufficient for performing this operation. (rsAccessDenied)"

When I hit the site, everything worked fine for me.. then again... Im an "owner" throughout my site... so that doesn't prove much.  I also saw that I'm inheriting permissions from the parent site, where all domain users have read access.. so the user can see the report, they just can't execute it.  I spent a few hours looking at database permissions, SSRS report properties, etc.  In the end, I mistakenly uncovered the solution.

My SharePoint site has publishing features enabled, which is kind of nice.. but some things are treated as "private" until their approved.  With reports, that means data connections.  In my site, I wound up in my Data Connections Library (which should be visible after clicking Site Actions -> View All Site Content).  Within my data connection library, the approval status on my data connection read as "Pending"



Once I edited the data connection (hover over the name, expand the drop down that appears, and click Approve/Reject), and set the connection to Approved, all was right with the world once again.  Odd issue.. but happy in the end it was such a simple solution

Tuesday, December 11, 2012

Recurring Error After Adding an ASP.NET 4.0 application to a subdirectory on SharePoint 2010

So a few weeks ago I was proud as a peacock after I got a 4.0 web application hosted as a SharePoint subdirectory, mentioned here: http://www.ericjamesw.com/2012/12/adding-aspnet-40-application-to.html

I'm trying to update the authentication mode of my SharePoint install to use Kerberos, and had to flip some settings on and off in Central Admin in the process.  Low and behold, my sub application broke, and started giving me yellow screen errors.  I found in my Windows Event Logs that the "Target Framework Attribute" was unrecognized, and before I knew what hit me, I was back to square one with hosting my sub application!

What Happened? 

Well, when messing around with the authenticaiton settings, the SharePoint configuration files were updated, wiping out my custom changes in the process.  Fortunately, reverting to our previous changes was simple. 
  1. My sub application switched it's application pool back to the Default - 80 SharePoint pool, rather than my .NET 4.0 framework pool I had created specifically for this application.
  2. With the appropriate framework applied to my application again, I was now receiving "there is a duplicate ... section defined" error again. My SharePoint web.config was reverted (as mentioned above), removing our customizations!

    Thanks to Microsoft, they made our rollback easy, but it's good to know that this stuff can occur. When the config update was made, a previous version was stored in the directory ABOVE our SharePoint implementation, with the date and time appended to the filename. As such, I have the following:

All I had to do here was take my most recent config from this directory and move it into the "80" subdirectory, where my SharePoint intranet is running, and I was back to where I was before I tinkered with Kerberos and other settings. 

Thursday, December 6, 2012

Career Tips For the Future IT Professional

Last night was the last classroom meeting for the course I have been teaching, CIS 108 - Intro to Technology.  The class met once a week for 3 hours per meeting where I usually offered homework for each week as well containing a quiz on the chapter discussed in class, and a video to watch\discuss in a discussion board.  Most weeks I had chosen videos from TED.com that discussed a range of topics from Who Are Hackers to capturing video at fentometer speed to what physically makes up the Internet to data transmission via light.  All in all, my students seemed to enjoy the video topics.

Since we hit the end of the semester, I had compiled a list of items I thought would be helpful to a future IT professional.  The educational model in America has shifted enormously over the past 20 years or so.  A college degree used to be a ticket to a new job\career, where now employment is more of a buyer's market.  Everyone has a degree, you all look the same on paper, and often the question asked is:

How do I get a job if I have no experience, yet I cant get experience because no-one will hire me!?

First of all, I phrased that question in such a way because of how negative it is.  If you find yourself asking this question, in a same negative tone, re-frame your perspective on your job search, don't be a defeatist.  Secondly, you need other means to grow and prove your technical aptitude outside the workplace.  This isn't a bad thing, because all experienced, quality and successful technologists develop and hone their skills both inside AND outside their workplace as well.  Do you want to be successful?  Well.. why not do what other successful people do?  Novel concept, eh?

So, the items below were part of my final presentation to my class.  Some students just started their college career's, others were taking IT classes part time, while remaining in the workforce in other industries.  I wanted to offer suggestions for my students to help them develop a professional resume, while not yet being a true professional.  I'm sure I will twist and tweak these items over time, but wanted to offer them nonetheless.

Career Tips

1. As soon as you can, create a professional profile.. and start building it out. These things can grow over time, but make an excellent resume builder.

  • Go buy a domain name (theyre really cheap), I use godaddy.com.
  • Go to blogger.com, create a new blog
  • Associate your domain name with godaddy.com – online help file helps you. This way, your blog now powers www.yourdomain.com, looking very professional to future employers
  • This whole process takes 10 minutes

2. With your blog setup, publish!

Publish your thoughts, results of your school work, "interesting" tech articles from cnet, slashdot.. whatever.. this becomes a great resource to show your technical aptitude when you otherwise have little to no experience in the workplace.  
  • Create a PROFESSIONAL twitter account - not the one where you tweet how drunk you were last night, or how you ate too much pizza, but one where you can discuss things your mom wouldn't be offended by reading.  Use this account to post\link similar ideas and concepts discussed in your blog above. 
  • Create a LinkedIn account - add EVERYONE you know, and keep in touch, jobs happen because of people more often that a resume submission
  • Associate your domain with your linkedin, resume, wherever you can post it

3. Clean up your FaceBook profile

  • Remember, you can be "tagged" in pics, so anything of you doing anything you shouldn’t be doing, you should get rid of.  After all, if issues like this haven't taught us by now.. nothing ever will

4. Scour Monster, CareerBuilder and Dice for jobs you might be interested in

  • Get a feel for job needs based on the technology
  • Get a feel for salary in the area your researching to live in
  • Get a feel for relevant skills, what types of jobs are out there, but what are these positions looking for? Windows? Linux? Particular networking equipment? Certifications? Programming Languages?

5. And realize that sometimes the best jobs aren’t landed through Monster and CareerBuilder

  • Its also who you know, have that friend of a friend of a friend get you in touch with their boss.. who happens to be looking for an IT pro.  Check out The Power of Who to learn how landing your next job isn't because you filled out 1,000 resume's!
  • It's through Internships - paid\free internships give you great in-field knowledge, and build a resume, and potentially lead to a full time job
  • It's through “free” work, such as charities - much like internships, "free" work lets you build your technical skillset, and look fantastic on a resume.  Reach out to local charities and ask if they need any help from a technical perspective.  Chances are, if they don't need help, they may know someone who does..

6. Books - You should ALWAYS read.. always, always, always. 

Especially in the IT world, concepts are always changing.  If you're not much of a reader, change that habit, challenge yourself and do it.  I hardly ever read Fiction, some of my personal favorites I've read (in no particular order):
  • Drive - Daniel Pink - Misconceptions and solutions to what people's real motivations are in live
  • Total Money Makeover - Dave Ramsey - Solutions for personal finance to help you relinquish debt and build income, I almost feel this should be recommended reading for any student BEFORE they take out school loans!
  • Outliers - Malcolm Gladwell - Discusses topics like why Bill Gates was so great, how Korean airlines went from the worst to among the best airlines because of a cultural issue, or why most professional hockey players are born Jan-March. All in all, great perspective on what can make you great in your career
  • Einstein His Life and Universe - Walter Isaacson - Think of someone influential and learn about them, provides amazing perspective. For me, this was Einstein
  • Linchpin - Seth Godin - Learn how to be a key resource in your workplace, and why you can be almost indespensible
Oh, and you can get all of these used for under 10 bucks each. Remember that you are the same person every year, except for the people you meet and the books you read

7. Take Free Classes, now, or whenever you graduate

  • EdX.org - Harvard\MIT classes lead and designed by Harvard\MIT professors.. for FREE!
  • iTunes U - recorded presentations from leading universities
  • Never stop learning...
Over time, I try to think of concepts that either helped me land my first job, or things that would have helped me grow my career over time.  In the end, none of these items above are quick wins or silver bullets, they're really just several individual concepts that can help you round out your career and professionalism over time, but the sum total is worth more than it's individual parts.  Hope this helps!

Monday, December 3, 2012

Adding an ASP.NET 4.0 application to a subdirectory on SharePoint 2010

My SharePoint 2010 site is running under SSL, and I have some web applications I want to keep as separate applications (aka, not publish them to SharePoint), and just have a web part page with a web page viewer.  This way, the page is harnessed within SharePoint, so it still has my SharePoint header\navigation, but its only showing a web application from https://intranet.myorg.com/MySubApplication

For setting this up, most of this was straightforward in that we had to create an "application" in IIS (7.5) underneath my SharePoint site, but I quickly hit a snag.  SharePoint 2010 runs under an ASP.NET 2.0 application pool.  Since 2.0 is old, I wrote my application in 4.0, so my parent (SharePoint) site is 2.0, but the child application is 4.0.

The issue here is that some settings\configurations are loaded because of the 2.0 framework, and launching the 4.0 framework application is also trying to inject similar settings, causing all hell to break loose (OK, just an error page.. but a sternly written one I must say).  To resolve, I did quite a bit of googling, and a little bit of loose translating from here:  http://translate.google.com/translate?sl=fr&tl=en&js=n&prev=_t&hl=en&ie=UTF-8&layout=2&eotf=1&u=http%3A%2F%2Fsamsonfr.wordpress.com%2F2012%2F07%2F24%2Fintgrer-une-application-asp-net-mvc-3-sous-un-site-web-iis-hbergeant-sharepoint-server-2010%2F

In short, if you have to add a .NET 4.0 application as a sub-application to your SharePoint 2010 implementation, start with the usual steps, which are: 
  • Create a new application pool targeting the 4.0 Framework. 
    • If possible, give this the same identity to run under that your SharePoint site is running as. 
  • Then, create your directory on the server that will host your 4.0 application, and link to it within IIS (right-click the SharePoint web and click Add Application). 
  • Go ahead and deploy your application, and try to browse to it. 
If your in a similar spot than I, then you should have an error message similar to a 500.19, barking about a configuration error and that there is a duplicate <somethingOrOther> section defined.  To resolve...

  1. In your sharepoint web.config, we need to prevent inheritance of parent (sharepoint) settings, I surrounded system.web with:
    <location inheritInChildApplications="false" path=".">
    and
    </location>
  2. Also within our SharePoint config, I commented out the system.web.extensions section group (and everything within it), and added it to the .NET framework's 2.0 web.config, found at c:\windows\microsoft.net\framework64\v2.0.50727\config\web.config
  3. I then added the following to the modules section to my application's config file, to prevent these modules from inheriting
    <remove name="SPRequestModule"/>
    <remove name="PublishingHttpModule"/>
    <remove name="RSRedirectModule"/>
    <remove name="StateServiceModule"/>
    <remove name="SharePoint14Module"/>
At this point, I was still getting 500 error's, but the error message wouldn't even display for me.  Much like the aforementioned article, I had to enable Failed Request Tracking in IIS.  Once I did so, I found that the following error was occurring:
"Handler PageHandlerFactory-Integrated has a bad module ManagedPipelineHandler in its module list. 

Some more googling led me down the path that the 4.0 Framework wasn't installed properly.  That didn't make much sense to me, but it was easy enough to open a command line and execute: %windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -i
Once I did so, my application started working.  Hope this helps!