newtelligence poweredRSS 2.0
# Thursday, January 22, 2009

By way of Scott on twitter, I discovered the Google Ajax APIs today (thanks to Douglas Purdy for the original tweet). The playground area allows you to see all of the APIs in action. Taking a step back, you can view all of the APIs that google provides by visiting this URL: http://code.google.com/more/.

 

All you need to get started, is to sign up for a free API key, which you can do here. Then just add a script src tag to your page referencing your API key (http://www.google.com/jsapi?key=ABCDEFG) and you are good to go. I would recommend reading at least the Getting Started guide under documentation. In addition to the stuff you would expect, like search and maps, they also have language translation and visualization (charts and graphs) to name a few. They also provide up to date versions of common APIs like JQuery, relieving you of the burden of managing these resources on your own.

 

While I would certainly use the Google APIs for accessing Google content, I am a little concerned over some of the other offerings. I would prefer to control when I update my JQuery library for example (how do I know if there are any breaking changes)?

Thursday, January 22, 2009 8:51:24 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
Review For Future Projects
# Sunday, January 11, 2009

Microsoft announced this week a new product offering in beta, Microsoft Tag. Microsoft tag uses high capacity color barcodes allowing for more information then traditional 2D barcdoes in a smaller footprint (.625” vs 1.25”). Microsoft Tag includes a web site where you can create, manage and track your tags, and a mobile phone application that allows you to scan the tags using the camera built into your phone.

Seeing as I already have a box of several thousand business cards (and give away about 10 each year), asking my company to reprint a new batch of cards, with support for the 4 colors required by the barcode (there are reports that you can use grayscale and other monotone color schemes, but these are unsupported) is not an option. So instead, I am going to use a color printer and some mailing lables to retrofit my existing business cards.

  1. Sign up for a Microsoft Tag account. It’s free, and all you need is a windows live ID
  2. Create your tag. I created a tag of type URL
  3. Render your tag. I tried the WMF, but kept getting a black background. So instead I exported to PDF, and then took a screen shot using the built-in capture tool in Foxit PDF Reader
  4. Paste image into Paint.Net as a new image
  5. Create a new layer to add additional text and save
  6. With your new layer selected, press ctrl+M to merge the layers into a single image, then select all and copy
  7. Paste the full size image into MS Word
  8. Right click the image and resize to fit your label, in my case 2.6” x 1”
  9. Re-copy the smaller image, then go to labels under the Mailings ribbon option
  10. click the labels tab, then click options to select your label type
  11. Paste your image into the Address field. It won’t show up, but if you click and drag like you are selecting text, you should see it highlighted at least. I don’t know if it’s a bug, or if pasting an image isn’t 100% supported.
  12. Click Print. I printed to my black and white printer a couple of times to make sure everything looked OK and lined up on the labels before switching to the color printer and the label stock
  13. If you need to re-adjust the image, just re-paste into word, and re-copy. It should update the image in the label screen without having to re-paste.
Sunday, January 11, 2009 11:44:07 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -

# Friday, January 02, 2009

This week I started working on my first Asp.Net MVC project. The requirements I am working with approximately 5 pages or views, and is read-only in nature, which I thought would be perfect for trying out the MVC stuff. I am also trying to take a incorporate some other methodologies, tools and techniques I have been reading up on, including:

  • Domain Driven Design (DDD)
    • Repository Pattern
    • Your not going to need it principle (YNGTNI)
    • Keep it simple stupid (KISS)
  • Test Driven Design (TDD)
  • Mocking (RhinoMocks)
  • Inversion of Control (Ninject)

So far the project is going really well. I’ve created all of my views, controllers, and basic page navigation, including some URL validation that redirects the user to a page when a parameter is missing from the URL (id part of the default route).  I’ve also added Inversion of Control using the Ninject framework, which I am using to specify my data store type (In memory for testing, or a Sql based store for actual data). I choose Ninject due to it’s small footprint, focused feature set, and Compact Framework and Silverlight compatibility (while not needed for this project, I have a use for that level of compatibility on another project and wanted to limit the number of frameworks I’m using).

CodeBetter: I should have thrown this out in the beginning, but I’m using the Foundations of Programming Ebook and learning application written by Karl Seguin as a starting point. I highly recommend it for people looking to get into the Alt.Net mindset (DDD, TDD, mocking, etc).

Solution Structure: At the start of this project, I was working up an elaborate solution (directory) structure, where I would separate out my Infrastructure, MVC, Domain, and Data Stores into separate projects. I quickly realized, that this wasn’t needed based on my requirements, nor did it follow KISS or YNGTNI. Instead, I separate out my concerns in the MVC project using namespaces. Since I am making heavy use of Unit Testing, if the need ever arose I could split stuff out into separate projects in less then a day, update my tests and be good to go. So in the end, I have one MVC project, a unit test project, and a Web Test project.

TDD: I have two testing projects, one for unit tests, using Xunit, RhinoMocks, and TestDriven.Net. This project tests all of the code for the model/domain, controllers, and infrastructure. My other project uses MSTest and is for my Web Tests, which are more of integration tests. There are some things you just can’t unit test that well, like did the menu get hidden when no account number was present in the URL.

Routes: I am using the default route Controller/Action/Id that comes with the sample project. This fits my requirements perfectly, as I need the Id part for an account number. My requirement was to have a URL in the form of http://Website/Home?Account=123456 which I was able to change to http://Website/Home/Account/123456

Code Behind: I’ve gone ahead and removed all of the code behind files on my views and user controls to make sure I don’t take any shortcuts with the code behind files. I’ve read several work around's for getting strongly typed views without a code behind file, so I’m covered there. By removing the code behind you eliminate 2 extra files per view/user control (ViewName.cs and ViewName.Designer.cs). Just remove the AutoEventWireup and Codebehind attributes in your view, and change the inherits attribute to System.Web.Mvc.ViewPage or ViewUserControl

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

Passing Id: One thing I found out I needed to do often, was construct a URL the conformed to my routing. Thankfully there is a helper method you can use in your view called Html.ActionLink, which has several overloads. I’m using the overloaded method that takes the name of the controller, action, an object for values, and an object for html attributes. Getting the object passed for values was not apparent right away, but you make use anonymous types.  The following code creates the following link, Home/Account/123456 (assuming ViewData[“Id”] is set to 123456), and gives it a text value of Home.

Html.ActionLink("Home", "Account", "Home", new { id = ViewData["Id"] }, null)

Filters: As I mentioned before, in using the default route, I’m “mapping” id to an account number. If there is no account number present, or the account number does not correspond to an actual account, I need to take some action. At first I had a helper method that I would call from each action that needed the account number, and redirect to a certain view if the account number was missing. Then I read about filters, and the OnActionExecuting override in the controller object, and thought that would be a better way to go. However, I’m going to go back to calling a method in each action for the following reasons:

  • Easier to unit test. With OnActionExecuting override, I havn’t been able to find a way to unit test the method or the overall behavior.
  • Code Smell. While one could argue writing the same line of code in each each action method smells, it is not as bad as having to check for certain action names in OnActionExecuting. For example, I didn’t want to redirect to the account entry page if I was already there. This way, I can call the method only on the action methods that need it.
  • Easier to understand. To the uninitiated MVC programmer, it’s simpler to follow then attributes or a base class override.

That’s all for now. I’ll try to write an update after I finish the project. I need to work with grids, and the new MS Charting controls, so that would be worthy of a follow up post.

Friday, January 02, 2009 2:23:06 AM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
Programming
# Friday, December 26, 2008

For the first time in almost a year, I had to do some BizTalk development (actual BizTalk development, not the support tool I wrote about previously) to support our old system. We were making a change to one of our schemas, but need to send a message that conforms to the original schema version on one of our send ports. The easiest way I could think on how to accomplish this, would be to add a map on the send port that transforms the message from the new schema to the old schema. Seeing as I’m was a little rusty on my BizTalk dev skills, this took a little longer then expected.

First, the schema I was dealing with had an element comprised of child elements, whose Group Order Type property got changed to sequence. This resulted in errors such as “Element E1 has unexpected child element E2 in Schema, list of possible elements include E3”. It would be nice if the error message was a little more clear. I even ran the schema thru a web based XML validator I found and got the same error message, so that must an error message in the XML spec. I finally figured out what was going on by looking at a sample XML message created using the Generate Instance fucntion and saw that only 1 of my “required” elements was showing up. Changed the Group Order Type to sequence fixed my problem.

With my test message passing the schema validation, I moved on to creating the map. I created a new assembly to hold the map, as well as the destination schema type. I then referenced my existing assembly to get the source schema for my map. This was pretty straight forward, and I was able to build and deploy my updated and new assemblies to BizTalk. Trying to keep things simple I set up 1 receive port/location and 2 send ports along with some content based routing. On one send port, I applied my map, and the other I did not. After sending a test message thru, I saw that both my send ports produced a file, but neither were transformed as expected.

Turns out I forgot to set the receive pipeline to XMReceive…I know I’m a bit of a BizTalk newbie sometimes. You do not need to change the pipeline from pass-thru on the send port, just on the receive location. After correcting this, my message suspended out with the error: “Cannot locate document specification because multiple schemas matched the message type http://Fully.Qualified.Schema#RootNode.” This makes sense, as all I did was copy/paste my original schema to the new schema file to preserve the existing structure, and then modified the original file, adding my new elements. I also needed to modify the schema on the new version, indicating a new version (which we happen to include as part of the namespace).

At this point things started working as I had originally envisioned. BizTalk is not something I can quickly jump back into for some reason. There is a bit of ramp up time to get back into the swing of things. I should probably go find some more BizTalk stuff to fix while I’m in the right frame of mind.

Friday, December 26, 2008 11:05:05 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
BizTalk

Merry Christmas to me, my Dell Mini 9 arrived today. I ordered it with a 16GB hard drive and 1GB of ram and Linux. I have plans of installing Windows 7 beta after I get it from attending MSDN Dev Con next month, but there was no way I was just going to wait around with the mini not in use until then. The mini does not come with an optical drive, nor do I have access to a USB optical driver (although it might be a wise investment), so I needed to learn how to install from a USB storage device.

While I found numerous how-to’s, the following You tube walk thru, which uses a utility program from this forum http://www.boot-land.net/forums/?showtopic=4900 is the best way to go in my opinion. It takes care of formatting your USB device, coping files from your Windows XP CD or other location (i.e. if you use a program like vLite to create a stripped down XP install), and setting values for the unattended install answer file (a real bonus feature). Once I found the tool, it was pretty easy to get XP installed, and once XP is installed, it’s like any other computer, where you can just copy your network drivers from a standard USB thumbdrive, then access the rest of your files via your network. I also installed an ISO mounting tool to install applications like Microsoft Office which I store as .Iso.

So far I have the following installed:

  • Office 2007
  • Live Mesh
  • Live Writer
  • Combined Community Codec Pack
  • Pidgen + Simp
  • Foxit PDF Reader

Spent all day yesterday at the in-laws watching movies, surfing the Internet and reading some e-books and the mini worked like a champ. Battery time is around 4 hours which is pretty good on wi-fi, given the small, lightweight form factor. I can get over 3 hours on my wife’s new Dell studio 17, but it weighs in close to 9 lbs. I’m going to keep the mini at work and try to take meeting notes on it, hopefully being able to ditch my pen and paper.

I’m also looking for some type of mounting hardware so I can mount it on the station bike I use so I can use the mini to watch movies during my 2 hour endurance rides. I currently have an older 14” laptop that I take with, but I could easily get 4 hours worth of video playback time out of the mini if I turn the Wifi off. If I’m able to mount it to the station bike right in front of me, the 9” screen will be more then big enough.

I am very happy with my Mini so far, and I am looking forward to running Windows 7 on it in the near future.

Friday, December 26, 2008 8:46:24 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
Technology
# Monday, December 22, 2008

Opened up my OneNote notebook today on my primary work computer and noticed all of the notes I had entered over the weekend were not there. Reviewing the news tab on mesh (local copy), I saw that my last update was 4:37pm, but couldn’t figure out what the date was. I was able to correlate the times with the date/times shown on the full news feed on the Live Mesh desktop and figured out that I stopped syncing sometime last Thursday.

I was able to add news entries locally, but they wouldn’t show up anywhere else, and no changes made on my work computer would sync to any other location, in addition to my work computer not receiving any changes. I have another computer here at the office with Mesh installed, and it was working, so thankfully the IT staff at our parent company didn’t block another service at the firewall.

Here are some of the things I tried:

  • Sign out and then back in
  • Sigh out and exit and restart Mesh
  • Set Work Offline on/off
  • Reboot computer

Starting to get a little annoyed at this point. Looking at task manger, I could see both Moe and MoeMonitor there, but they wouldn’t do anything. Usually at start up they chew thru quite a bit of CPU. I decided to try to remove the sync setting for one of my folders, but got the error “503 Mesh service not available”. There was not much help via a Google search on the error message so it was time to resort to a reinstall. At first I tried the repair option offered in Add/Remove Programs (or what ever it’s called in Vista/Server2k8), and that more or less failed. It looks like it partially uninstalled, so I just went back in and did a full uninstall. Then I downloaded the 64bit client and re-installed.

Thankfully I’m back up and running and things seem to be working OK at this point. I’m hoping my conflicts were minimal. I read that there will be an update after the holidays with better conflict resolution which will be cool.

Monday, December 22, 2008 10:19:12 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
Technology

Did a 1500m swim test today and set a new personal best of 34:17, shaving another 45 seconds off my previous best. To put that into context, top pros swim 1500m in open water for the Olympic Distance Triathlon in about 18 minutes. So while that is probably outside my reach, getting down to 30 minutes seems like a reasonable goal, with a 25 minute time a stretch goal. Today, after watching my wife swim a couple of laps, I as able to better visualize what I was feeling in the water. Sine we are both starting out, we are making allot of the same mistakes. After my 1500m, I swam a couple of laps where I forced myself to go slow, and really try to focus on my technique. To my surprise, even though I thought I was going really slow, I was doing 25m in 30 seconds, which is the pace I need to hit my 30 minute goal.

You read allot about technique over raw speed, but most of the time (at least for me), I don’t believe it until I have some first hand experience, which I think I got today. It’s a fairly large psychological breakthrough, and I believe it will help me focus during future workouts. Some key points in my technique that I was able to put together for the first time today were: Full extension, shoulder rotation, smooth hand/arm entry setting up for my s-stroke. The pool is closed on Wednesday (my usual swim day along with Sundays), but my parents have an indoor pool at their condo and I’ll be on that side of town anyway. It’s probably closer to 10-15m, so I’m thinking of technique drills followed by lots of short sprints for the intensity component. Maybe I’ll swim around the edges to get more of a feel for a long distance instead of laps, as I always touch and stop at each end (still haven’t learned the flip turn).

Biking and running are coming along nicely as well. While I had a DNF during last weeks two hour endurance training (had to stop at 1 hour 47 minutes), I was averaging 227 watts. This week was a little better, as I finished very strong, but I had to stop at the 1 hour mark to use the bathroom. I’ve slacked off a bit on the intensity component for biking, while training to squeeze more running in, but I think I’m going to limit my running to one time per week until these shin splints clear up. Even though the shin splints are annoying, I was able to set a pretty good pace on Thursday, running on the treadmill for 30 minutes covering 4.5 miles (6:40 mile, 9 mph average). I would do 1 minute of 9.5-9.6 mph followed by 30 seconds of rest at 8.1 mph. This worked out really well, and I think I’ll keep working with this format to build up my speed and endurance.

I’m really looking to getting back outdoors for biking in the spring. I didn’t do any biking last winter, and my workout routine was sub-par compare to what I have been doing since April. I remember getting on my bike the first time and taking so long to bike to work that I was really disappointed (although it was maybe 50 out, and I had a strong head wind). I was able to build myself back up during the summer, but still couldn’t do much better then 21 mph average over my 12.5 mile route from my office to home. I’m really looking to a 24 mph average over that 12.5 miles in the early spring, and then keep that pace for 24-25 miles for the triathlon. I don’t know if that will be possible without more aero tires and at least clip on aero bars, but I’ll give it a try.

Monday, December 22, 2008 1:44:13 AM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
Fitness
# Monday, December 15, 2008

This morning I was greeted with a proactive alarm email stating that we had over 100 messages in our BizTalk suspend queue. What an awesome way to start my Monday morning. Sure enough, the Biztalk admin tool showed the messages suspended out starting around midnight, which first made me think that maybe somebody made a change somewhere. If you couldn’t tell from the title, the error message in the Event Logs as well as the Admin tool was: “The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel” (this is on a HTTP send adapter by the way).

The first thing I did was attempt to browse to the destination URL in IE from the BizTalk server. Everything worked, no errors or warnings, but here is something intesting the cert was recently issued last week. Now why would it take a week to start seeing errors, unless it wasn’t installed until last night? Sure enough, heard from customer that maintains the destination server, and they updated their cert over the weekend. So why was BizTalk having problems, but IE wasn’t?

It appears, that BizTalk must do some sort of caching, either on the cert or the HTTP connection. I’m not exactly sure what it does, but after restarting the host process, everything work fine. All the messages were resumed without issue and we’ve had no more suspend out.

Monday, December 15, 2008 5:00:04 PM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
BizTalk

Have you ever had one of those days where you just want to give up your job in computers/technology and go get a job at Walmart? I had one of those today, and I'm not even at work. I was just trying to setup some virtual machines to work on some projects at home, and nothing went right.

First I tried to install 8GB of ram into my main workstation at home. That failed and took me a couple of hours to figure out that I needed to manually adjust the memory timings and voltage in order to get all 4 stick of ram to work. Along the way I thought I would update the bios to see if that work, and ended up removing my raid-1 array from existence. I didn't see the warning on Gigabyte's page about re-enabling the Raid setting, but I did see it in a forum post, however I forgot to actually do this. So on the one hand it's party my fault, but on the other hand I think it's poor design that the Raid setting get's set to disabled on a bios update.

I didn't realize that I was missing my raid array for 4 hours or so. In the meantime, one of my other computers blue screened on me with a stop code of 1a while trying to copy a base VM image. Nice. I think I'll leave that alone for awhile.

Actually I was able to make some decent progress on getting my VM's setup on my primary workstation, until I realized I had a G drive, that had the exact same contents as my mounted data partition, that used to be my Raid array. Oh crap. Rebooted and re-enabled the raid setting, and the array definition was still intact thankfully. Back into windows and I still have a G drive and my mounted partition is no more.

Spent some time and a couple of reboots to get my Raid array mounted to an "empty folder" like I had it before. The raid monitoring utility said that everything was working, but I started getting errors popping up saying that I needed to run chkdsk. Again, several reboots later, I was able to run chkdsk and not get any errors. Final problem was that allot of my NTFS security permissions got messed up as well. I think it's all better now, as I was able to perform a defrag, and I'm running the raid application's analyze and repair utility as well. If I run into any more problems I'm going to have to backup 500GB worth of data and reformat.

Now on another PC, I was trying to setup Virtual Server, and the VM won't start, and pretty much crashes virtual center. Guess I'll try VMWare server instead.

Oh, and since I have a share on my primary workstation, which resides on my Raid Array that is part of my Windows Media Center library, Windows Media Center was pretty much non-functional until after it was back online. It just sat there trying to connect to a non-existent share....brillant. How do you explain that one to the wife?

Monday, December 15, 2008 4:42:21 AM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
Technology
# Monday, December 08, 2008

In part I, I talked about how I had a need for a way to managed suspended messages in BizTalk using something other then the BizTalk Administration tool. Using a combination of BizTalk dll’s I was able to query, read and suspend BizTalk messages. The need for a “web” based tool is one of accessibility to our BizTalk server from remote machines that are not directly connected to the DMZ zone that they reside in. I’ve also been wanting to create a tech support tool for myself to manage other aspects of our hosted solution, and this would fit in nicely with it.

Being a glutton for punishment, I decided to sacrifice my weekend and go for the more complex, but really cool sounding idea of a set of web services that interface with SilverLight 2. I choose SilverLight as I’ve been wanting to get my hands dirty with it for some time, and another member of the team was talking about doing the same, and what’s a little friendly competition? While I had a grand vision of what my tool would look like, which I will refer to as the Unified Administration Tool (UAT), I knew I wouldn’t be able to code everything in one weekend. I had to set some realistic goals and try to add only what was needed, while still allowing for future functionality to be “plugged-in”. The good thing was, since this was pretty much just for me, I didn’t have to worry about other peoples requirements ;)

The UAT is an n-tier application which will provide administrative functionality over our hosted solution that is distributed among several servers in different DMZ zones (as mentioned in Part I of the BizTalk Web Admin). In addition to dealing with the distributed nature of our servers, the tool must also account for the various environments, with one environment consisting of an instance of our solution deployed across one or more servers. Perhaps to put this more simply is that I wanted to be able to perform the same functions on our development, staging, demonstration and production environments.


I started out by created a new project folder to which all my various Visual Studio projects will be added. I moved my BizTalkUtilities projects into the Components folder as shown below, and then started adding the other components and UI projects as needed. Below is an overview of how I have my solution folder setup, which will probably change over time. The idea is that Components are reusable across all the UI and Services, and will probably have some more domain specific wrappers. Controllers under UI will be re-usable across each of the UI projects and provide an interface between the components and the UI.

  • UnifiedAdmin
    • _Solutions
    • Components
      • BizTalkUtilities
      • BizTalkUtilitiesTest
    • Documentation
    • Scracth (Prototypes and other throw away code used for quick tests)
      • BizTalkMessageBrowser (Test win forms app for BizTalk Utilities)
    • Services
    • UI
      • Controllers
      • Silverlight
      • SilverlightMobile (Future project)
      • WPF (Future Project)

I decided that I will use the Entity Framework as my “ORM”, combined with Ado.Net Data Services as my primary web services mechanism. Combined with Silverlight, I’ll get to tackle three new technologies at once, and either learn allot, or give up, ultimately frustrated, wishing I would have chosen a few older tried and true technologies. Before we even get to the UI, I needed to start setting up my services and entity model. I have a feeling I’ll be re-arranging some of these projects, but for now I have a class library called Entities under Components, and a web project called UnifiedAdminService under Services.

I really don’t know what the best practice way for organizing my entity models are, and it seems like one entity model per project seems a bit of an over kill, however, putting all the entities I will be working with in the same project doesn’t seem to smell good either, as there defiantly a clear break between them. I started out with an entity model for a database called Utilities, which will be the “glue” that holds my Unified Admin tool together. It’s sort of a catch all database that currently contains tables for some SQL based monitoring I have setup, as well as users (who can access the UAT), and servers (what servers does the UAT work with). I created a new Ado.Net Entity data model and had it auto generated the model from the database schema. This was pretty easy and straight forward. I prefix all my table names in my schema with various prefixes for grouping and identification, such as “mon_t” which means the table is used for the monitoring functionality, and it’s a table. I don’t want these prefixes in my code, so I am going to rename the entities in the model. To start with I’m only renaming a couple until I see how the EM is updated and used throughout the code.

Next I created a new Ado.Net data service in the web project. This created a new .svc file with a code behind file that inherits from DataService<T>. I updated T to reference my entity model (Entities.UtilityEntities) and also configured the security to allow read access for entities. You do this by using the config.SetEntitySetAccessRule method in InitializeService. 

public class TsiUtility : DataService<Entities.UtilityEntities>
{
   // This method is called only once to initialize service-wide policies.
    public static void InitializeService(IDataServiceConfiguration config)
    {
       config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
    }
 }

Even thought the auto-generated comments for InitializeService make it sound like it’s only called once in the life-cycle of an AppDomain, I wasn’t sure. This post talks a little bit about the InitializeService method, and does in fact point out that the InitalizeService method is only called once.

I attempted to browse to my newly created service and was greeted with an un-informative error, “The server encountered an error processing the request. See server logs for more details.”. Since I’m running the development server that’s included with Visual Studio, there are not much in the way of server logs (that I could find anyway). Jumping into debug mode showed that the error was caused by an incorrectly configured connection string. The connection string used my the Entity Framework is not your standard connection string, so you need to make sure that you copy the connection string created for you in your Entities project to your web.config in your web project (assuming your entity model is in a separate project). I was trying to use the Server, Database, Trusted_Connection syntax, and apparently that’s not OK.  Example connection string:

<add name="TsiUtilityEntities" connectionString="metadata=res://*/TsiUtility.csdl|res://*/TsiUtility.ssdl|res://*/TsiUtility.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=Server;Initial Catalog=Utility;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />

Once I had the correct connection string, I was able to navigate my entity model using just my browser. Of course I haven’t done any type of authentication, and I don’t want to have just anybody browse to the URL for the UAT and start browsing, so it’s time to add some security. Ado.Net data services makes use of existing security provides as long as they set the HttpContext principle, so you can use HttpContext.Current.User.Identity.Name and then compare that against records returned by the EM. Something that I didn’t fully grasp at first, was that by the time Ado.Net Data Services “takes over” the user should have been authenticated, so there really is no “login” event in Ado.Net data services where you can set additional information.

For simplicity, I decided to use Integrated Authentication, and store additional information after the user is authenticated. Since this is a regular asp.net application, you can add a Global.asax, and add code to the AuthenticateRequest event handler to perform additional security related code. When AuthenticateRequest is called, whatever mechanism that is configured to handle authentication has finished, and there should be a value in HttpContext.Current.User. What I did was user the Name property to query my users table that was part of my entity model and cache the results in a hash table, which itself is stored in the application context. If the user does not exist in the database, I set the Current.User to null, and cache a null value with the key of the user name that was authenticated.

protected void Application_AuthenticateRequest(object sender, EventArgs e)
  {
   string userName = HttpContext.Current.User.Identity.Name;

   //Get a collection of cached users. If it doesn't exist create and cache it.
   System.Collections.Generic.Dictionary<string, Entities.User> users = (Dictionary<string, Entities.User>)HttpContext.Current.Cache["Tsi_Users"];
   if (users == null)
   {
    users = new Dictionary<string, Entities.User>();
    HttpContext.Current.Cache.Add("Tsi_Users", users, null, DateTime.Now.AddHours(1), System.Web.Caching.Cache.NoSlidingExpiration,
     System.Web.Caching.CacheItemPriority.Normal, null);
   }

   Entities.User user = null;

   //Check to see if we have a cached user for this username. Use ContainsKey as we will store
   //a null value to indicate a user is not authorized.
   if (users.ContainsKey(userName))
    user = users[userName];
   else
   {
    Entities.TsiUtilityEntities entities = new Entities.TsiUtilityEntities();
    user = entities.UserSet.FirstOrDefault(u => u.WindowsUserName == userName && u.IsEnabled == true);
    user.ua_tx_UserServers.Load(); //load servers this user has access to.
   }

   //User doesn't exist in the database either, so un-authenticate them
   //allow to continue thru so we add a null object with the username to cache
   if (user == null || HttpContext.Current.User.Identity.IsAuthenticated == false)
   {
    //When this is set to null, this method should finish, but no data will display. 
    //Seems like aspx pages will still display though. However if you check the CurrentUser
    //it will be unathenticated.
    user = null;
    HttpContext.Current.User = null;
   }
   
   //save to users collection. Double check to make sure it wasn't added somewhere else.
   if(users.ContainsKey(userName) == false)
    users.Add(userName, user);
  }

What I have not decided upon, nor have I done the research into, is if I should be caching the DataContext in the application or session cache for the user.

So where does this leave me? Well, I certainly didn’t get even close to what I wanted to accomplish in one weekend, as I haven’t even touched SilverLight yet. I do have some basic authentication, but that’s more using traditional asp.net then doing anything special with Ado.Net data services. From the looks of it, I will have to add QueryInterceptors to every entity I wish to do security on, which seems like a pain and allot of extra un-necessary work. Next time I hope to accomplish the following:

  1. Research to find out if you should cache the data context
  2. Write out security requirements and research the best way to implement in Ado.Net Data Services
  3. Figure how I am going to have one set of services that can connect to multiple databases (assuming the database schemas are kept in sync).
Monday, December 08, 2008 3:09:26 AM (GMT Standard Time, UTC+00:00)  #    Comments [0] -
BizTalk | Programming
Archive
<January 2009>
SunMonTueWedThuFriSat
28293031123
45678910
11121314151617
18192021222324
25262728293031
1234567
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Copyright 2010
Adam Salvo
Sign In
Statistics
Total Posts: 234
This Year: 13
This Month: 1
This Week: 0
Comments: 34
Themes
Pick a theme:
All Content 2010, Adam Salvo
DasBlog theme 'Business' created by Christoph De Baene (delarou)