Entries in .net (9)

Monday
Aug302010

Raw HTTP Interactions from C#

I had a conversation with a friend last week who was messing around with a non-SOAP based HTTP service and was fighting with the C# necessary for rudimentary interactions. The problem was compounded by the fact that he needed to associate a certificate with the request to authenticate properly to the server.

I had recently been doing this exact thing based on some work with the Azure management API so I promised him some samples. As I was assembling them this morning, I decided to drop them here in case they could be beneficial to others.

The first sample shows a simple call wherein I build some XML and send it along with the request. In this case we are creating a deployment in Windows Azure. We then grab a value from the response header collection for use in the second call that has a simple request format but returns an XML blob in the body that I then parse to get the results I need.

Both requests are signed with an X509 client certificate – you’ll notice it referred to as “managementCertificate” – this is a variable passed in that was generated using the following code:

var managementCertificate = new X509Certificate2(manifest.CertificateFile);



Where manifest.CertificateFile is the path to the pem file on my local machine.



In the sample below, you’ll see the target URL built, some base64 encoding of some of the parameters (included just for completeness but just a requirement of the service I was calling). I then use a StringBuilder to build up an XML block and then setup the request with the certificate, xml blob, and other properties set. Finally, you’ll see the submission and then pulling a value from the headers collection to be sent back to the caller.



// Build uri string
// format:https://management.core.windows.net/<subscription-id>/services/
// hostedservices/<service-name>/deploymentslots/
// <deployment-slot-name>
var url = string.Format(
"{0}{1}/services/hostedservices/{2}/deploymentslots/{3}",
Constants.AzureManagementUrlBase,
subscriptionId,
serviceName,
deploymentSlot);

// Base64 encode configuration label and file
var base64label = EncodeAsciiStringTo64(configurationLabel);
var base64config = GetSettings(
instanceCount,
accountName,
accountKey,
queueSleepTime,
maxJobLength,
container,
queueName);

// build request body
StringBuilder blob = new StringBuilder();
blob.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
blob.Append("<CreateDeployment " +
"xmlns=\"http://schemas.microsoft.com/windowsazure\">\n");
blob.AppendFormat("\t<Name>{0}</Name>\n", deploymentName);
blob.AppendFormat("\t<PackageUrl>{0}</PackageUrl>\n", packageUrl);
blob.AppendFormat("\t<Label>{0}</Label>\n", base64label);
blob.AppendFormat("\t<Configuration>{0}</Configuration>\n", base64config);
blob.Append("</CreateDeployment>\n");

// encode request body then put it in a byte array
byte[] byteArray = Encoding.UTF8.GetBytes(blob.ToString());

// make request
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);

// header info
request.Method = "POST";
request.ClientCertificates.Add(managementCertificate);
request.Headers.Add(Constants.VersionHeader, Constants.VersionTarget);
request.ContentType = Constants.ContentTypeXml;
request.ContentLength = byteArray.Length;

Stream dataStream = request.GetRequestStream();

// write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);

// Get the response.
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

// Get the x-ms-requestID
string requestID = response.GetResponseHeader(Constants.RequestIdHeader);

// Clean up the streams
dataStream.Close();
response.Close();

return requestID;



In this next sample, we make a rather simple request but do more with the result in parsing the returned XML blob which is fairly trivial although it does have custom namespaces which have to be accounted for when you crawl the XML tree.



// Build uri string
// format:https://management.core.windows.net/<subscription-id>/services
// /hostedservices/<service-name>/deploymentslots
// /<deployment-name/
var url = string.Format(
"{0}{1}/services/hostedservices/{2}/deploymentslots/{3}",
Constants.AzureManagementUrlBase,
subscriptionId,
serviceName,
deploymentSlot.ToString());

// make uri request using created uri string
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

// make header, method, and certificated requests
request.Method = "GET";
request.ClientCertificates.Add(managementCertificate);
request.Headers.Add(Constants.VersionHeader, Constants.VersionTarget);
request.ContentType = Constants.ContentTypeXml;

// Get the response
HttpWebResponse response = (HttpWebResponse)request.GetResponse();

// put response into string text
StreamReader dataStream = new StreamReader(response.GetResponseStream());
string text = dataStream.ReadToEnd();

// create an xml document
XmlDocument xml = new XmlDocument();

// load up the response text as xml
xml.LoadXml(text);

// get the NS manager
XmlNamespaceManager ns = new XmlNamespaceManager(xml.NameTable);
ns.AddNamespace("az", Constants.AzureXmlNamespace);

// return the status
DeploymentStatus currentStatus;
var statusText = xml.SelectSingleNode("//az:Status", ns).InnerText;

if (Enum.TryParse<DeploymentStatus>(statusText, true, out currentStatus))
{
FullDeploymentStatus fullStatus = new FullDeploymentStatus()
{ MainStatus = currentStatus };

// now try to get the status values for each instance
XmlNodeList instances = xml.SelectNodes("//az:RoleInstance", ns);

foreach (XmlNode instance in instances)
{
var instanceStatus = new InstanceDetails()
{
RoleName =
instance.SelectSingleNode("az:RoleName", ns).InnerText,
InstanceName =
instance.SelectSingleNode("az:InstanceName", ns).InnerText,
Status = (InstanceStatus)Enum.Parse(typeof(InstanceStatus),
instance.SelectSingleNode("az:InstanceStatus", ns).InnerText)
};

fullStatus.Instances.Add(instanceStatus);
}

return fullStatus;
}
else
{
throw new ArgumentOutOfRangeException("Status",
"The status returned for the deployment is outside the range of " +
"acceptable values");
}



That is about it. Hopefully this is helpful and give you more comfort interacting with HTTP-based services that aren’t simply a matter of pointing at a WSDL and having magic happen.

Thursday
Sep032009

“Live” Monitoring Of Your Worker Roles in Azure

gauge

I’ve been working for a bit on some larger-scale jobs targeting the Windows Azure platform and early last week had assembled a collection of worker roles that were supposed to be processing my datasets for a number of days moving forward. Unfortunately, they wouldn’t stay running. As always, they “worked on my machine”, so I naturally assumed that the problem was with the Azure platform :). I then proceeded to do what I thought was the correct action… go to the Azure portal and request that the logs be transferred to my storage account so I could review them and fix the problem. What I learned, is that there were two problems with this solution:

  1. The time delay between requesting the logs and actually being able to review them is prohibitive for productive use. In my experience, the minimum turn around was 20 minutes and was most often 30 or longer. I’m not sure why this was happening – is this by design, or a temporary bug, or an artifact of the actual problem with my code, or what, but I know it was too long.
  2. Logs appear to get “lost”. In my scenario, my worker roles were throwing an exception that was un-caught my by code. Near as I can tell, when this happens, the Azure health monitoring platform assumes that the world has come to an end, shuts down that instance, and spins a new instance. While this (health monitoring and auto-recovery) is a good thing, one side effect (caveat is the fact that this is my experience and may not be reality) is that the logs were stored locally and, when the instance was shutdown/recycled, those log files went to the great bit-bucket in the sky. I was stuck in a failure mode with no visibility as to what was going wrong nor how to fix it.

After pounding my head for a bit, I came up with the following solution – trap every exception possible and use queues. The first aspect allowed my worker roles to stay running. This may not always be the right answer, but for my use case, I adapted my code to handle the error cases and trapping / suppressing all exceptions proved to be a good answer. Further, doing so allowed me to grab the error message and do something interesting with it.

The second step (using queues) solved the (my) impatience problem. I created a local method called WriteToLog that did two things: write to the regular Azure log, and write to a queue I created called status (or something similarly brilliant). I replaced all of my “RoleManager.WriteToLog()” calls with calls to the local method and I then wrote a console app that would periodically (every few seconds) pop as many messages as it could (API-limited to 32) off of the status queue, dump the data as a local csv for logging and write the data to the screen. This allowed me to drastically reduce the feedback loop between my app and me, enabling me to fix the problems quickly.

There are certainly some downsides to this approach (do queues hit a max?, what is the overhead introduced by logging to a queue, once a message is dequeued, it is not available for other clients to read, etc), but it was a nice spot fix. A better implementation would have a flag in the config file or something similar that would control the queue-logging.

As you can see from the image above, I also wrote a little winform app to display the approximate queue length so I’d have an idea of the progress and how much work remained.

Friday
Jun262009

Codestock Session

codestock I’d like to thank all of you who attended my session today at CodeStock. I had a great time talking with you all and sharing my experiences with SharePoint and TFS with you all.

Downloads from today’s session:

Also, I promised a collection of links for the tools I had installed.

Tuesday
Jun232009

Customizations to STSDev 1.3

As part of my session on Deployment and build using TFS and SharePoint for CodeStock 09 I took the source code from the STSDev project on CodePlex (http://stsdev.codeplex.com) and made a number of modifications. Some of these I would classify as clearly bugs, but most of them are simply adjustments to the core to fit my needs/desires. I’m documenting them here and providing a zip of the source for the benefit of those attending my session. These changes and source code are completely unsupported and you use them at your own risk. That being said, I hope that they are helpful and speed you in your integration between SharePoint and TFS. NOTE: unless specified, all of these changes are to the “Core” project.

  1. First minor change is that I moved the solution file up one level to the parent folder. This is truly nothing but a nit-pick but seems to make source control trees happier and therefore something that I almost always do.
  2. Upgraded the projects/solutions to Visual Studio 2008
  3. Added an app.config file with an assembly binding redirect pushing old references to Microsoft.Build.Framework to utilize version 3.5.0.0. This is one of the changes needed to get support for .NET 3.5 working properly.
  4. Changed the target framework property for the stsdev.csproj to .NET Framework 3.5. This change, in concert with the previous, allows the 3.5 selection in the UI to work properly.
  5. Major Change: Support for alternate bin paths. The 1.3 version as published on CodePlex always uses the compiler output in projectdir\bin\debug when assembling the *.wsp file. This happens regardless of what build configuration you have selected (yes, even release). This doesn’t work for TFS builds since the output is, by default, in a different location on the build server. To support this use case, the following changes were made:
    • Program.cs: Changes were made prior to calling SolutionBuilder.RefreshDeploymentFiles to support the passing in of an additional parameter indicating the alternate bin path.
    • Changed the Create method of Builders\DeploymentFiles\CabDdfBuilder.cs to accept the alternateBinPath as an additional parameter.
    • Changed the Create method of Builders\DeploymentFiles\CabDdfBuilder.cs such that, if an alternate bin path is provided, it will use that value when adding references to assemblies rather than the otherwise-hard-coded /bin/debug/
    • Updated the first overload of the RefreshDeploymentFiles method in SolutionBuilder.cs to pass the alternate bin path to the second overload of RefreshDeploymentFiles.
    • Updated the second overload of the RefreshDeploymentFiles method in SolutionBuilder.cs to build the TargetPath from the alternateBinPath if provided and otherwise to use the default.
    • Updated the second overload of the RefreshDeploymentFiles method in SolutionBuilder.cs to pass the alternateBinPath parameter to CabDdfBuilder.Create().
    • Updated the CompleteSolution method in SolutionBuilder.cs to pass an empty value for alternateBinPath to RefreshDeploymentFiles since, during the initial project creation, it is ok to utilize the default /bin/debug path.
  6. Major Change: When creating a project, always create a parent solution directory in the same way that Visual Studio defaults to. This is helpful when working in a source controlled environment with multiple projects in the same solution. To support this feature, the following changes were made:
    • Changed the <REFRESH /> property in Resources\Common\Microsoft.SharePoint.targets.xml to utilize the $(ProjectDir) variable rather than $(SolutionDir).
    • Changed the Create method of SolutionFiles\SolutionFileBuilder.cs to accept the solution directory as an additional parameter.
    • Changed the Create method of SolutionFiles\SolutionFileBuilder.cs to change the directory for where the solution file is created
    • Changed the Create method of SolutionFiles\SolutionFileBuilder.cs to reference the *.csproj file in subdirectory rather than in the same directory as the *.sln file.
    • Added  a property called ProjectDirectory to SolutionBuilder.cs to hold the full path to the project directory (now distinguished from SolutionDirectory).
    • Updated the RunCreateSolutionWizard method in SolutionBuilder.cs to set the Project Directory property.
    • Updated the InitializeSolution method of SolutionBuilder.cs to create the new (child) project directory and update the location appropriately
    • Updated the InitializeSolution method of SolutionBuilder.cs to set the SolutionBuilder.TargetPath based on the ProjectDirectory property rather than the SolutionDirectory value.
    • Updated the CreateDeploymentFiles method of SolutionBuilder.cs to use the proper path for the files (based on ProjectDirectory).
    • Updated the RefreshDeploymentFiles() (first overload) method of SolutionBuilder.cs to optionally set the ProjectDirectory property if it isn’t already set.
    • Updated the second overload of the RefreshDeploymentFiles method of SolutionBuilder.cs to set the current directory to the value of ProjectDirectory if it is set, and otherwise to use the SolutionDirectory value.
    • Updated the second overload of the RefreshDeploymentFiles method of SolutionBuilder.cs to utilize the ProjectDirectory value rather than the SolutionDirectory path.
    • Updated the LoadSolutionConfigFile method in SolutionBuilder.cs to use the ProjectDirectory property and remove the pathing ambiguity that was leading to incorrect path lookups.
    • Updated the CompleteSolution method in SolutionBuilder.cs to pass the SolutionDirectory property to SolutionFileBuilder.Create() since it can no longer assume that the solution file should be in the same directory as the project file.
  7. Major Change: Added support for the Release|AnyCPU project configuration to support integration with TFS Build. In support of this feature, the following changes were made:
    • Added <REFRESH-TEAMBUILD> property in Resources\Common\Microsoft.SharePoint.targets.xml file. The value of this property is similar to that of <REFRESH /> but has an additional parameter referencing the alternate bin path that TFS creates by default.
    • Added a Release target in Resources\Common\Microsoft.SharePoint.targets.xml. This is targeted specifically at the TFS build and is therefore similar to the ReleaseBuild target but calls the $(REFRESH-TEAMBUILD) exe rather than $(REFRESH)
    • Added a “Release” value to the Configurations string array in SolutionBuilder.cs. This causes the release config to be added to the generated solution and project files.
  8. Major Change: We utilize SharePoint Installer to create a nicely-packaged version of the resulting solution making it nearly brain-dead easy to install a new solution. The only real thing unique or project-specific in a SharePoint Installer package is the setup.exe.config file that passes a number of parameters to the executable allowing it to adapt for your particular solution package. This feature change causes STSDev to generate the initial draft of this file and to add it to the solution items. To this end, the following changes were made:
    • Created a new file, SolutionFiles\SetupConfigFileBuilder.cs to represent the template and logic for the SetupConfigFileBuilder class.
    • Updated the CompleteSolution method in SolutionBuilder.cs to call SetupConfigFileBuilder.Create and create the new config file.
    • Updated SolutionFiles\SolutionFileBuilder.cs to include a pointer to setup.exe.config and thereby include it in the solution.
  9. Major Change: We utilize Sand Castle and Sand Castle Help File Builder to produce developer-targeted API documents for our projects. Sand Castle Help File Builder needs a configuration file (xml) with a number of property values to configure it to run properly. This feature allows the basic file to be generated by STSDev and for it to be added to the solution items collection. To this end, the following changes were made:
    • Created a new file, SolutionFiles\SandcastleHelpFileBuilder.cs to represent the template and logic for the SandcastleHelpFileBuilder class.
    • Updated the CompleteSolution method in SolutionBuilder.cs to call SandcastleHelpFileBuilder.Create and create the configuration file.
    • Updated SolutionFiles\SolutionFileBuilder.cs to include a pointer to the generated *.shfb file and thereby include it in the solution.
  10. Major Change: By default, STSDev would not only generate manifest.xml and the ddf file, but it would add these files to the project. While in many cases this is innocous, it causes heartburn in a source-controlled environment. Firstly, purely generated files have no business being in your source tree. Secondly, since the user doesn’t edit them, once they are checked in, they are most often left as such, resulting in errors on compile because the files are marked as read only, preventing stsdev.exe from updating them properly. To this end, the CreateDeploymentFiles method of SolutionBuilder.cs has been updated to remove the calls to ProjectBuilder.AddSourceFile() following ManifestBuilder.Create() and CabDdfBuilder.Create().
  11. Added an image, PlanetIcon.gif to the resources section and replaced all hard-coded references to africanpith.jpg with references to PlanetIcon.gif. This is nothing more than a branding change for the output projects and has no other affect on the program’s functionality. Affected files include: stsdev.csproj, SolutionProviders\SimpleFeatureSolutionProvider.cs (AddSolutionItems method), Builders\SourceFiles\FeatureBuilder.cs (Create method)
  12. Adjusted the InitilaizeSolutionProviders method of  UserInterface\SelectSolutionType.cs to select by default the Web Part Solution (C# Assembly) project type on load rather than the empty solution. This change is nothing other than a convenience feature during testing and use (that’s almost always the project type I use).
  13. Adjusted the RefreshDeploymentFiles method of SolutionBuilder.cs to fix some seemingly obvious bugs in Console output using incorrect values.

Following the session on Friday, I’ll update this post with the actual source code and any other changes made during the presentation.

Monday
Jun222009

Speaking at CodeStock

Join me at CodeStock

I’m privileged to have been given the opportunity to speak at CodeStock (details below) this coming Friday. I’ll be speaking on the topic of Deploying and Packaging SharePoint solutions using TFS. The abstract for my session is:

Have you been using the VS Extensions for SharePoint to create SharePoint packages and found yourself wondering how best to integrate with your source control platform and build system? Consistent packaging of SharePoint solutions can be a challenge and is not for the faint of heart. Come to this session and learn how our team utilizes TFS, Team Build, SandCastle, SharePoint Installer, and STSDev in concert to produce consistent installation packages for our SharePoint/MOSS environment.

CodeStock is about Community. For Developers, by Developers (with love for SysAdmins and DBAs too!). Last year an idea started at CodeStock to mix Open Spaces within a traditional conference. This year we're going to crank things up to 11 and rip off the knob - and you're being drafted to help!

  • Keynote by Microsoft RIA Architect Evangelist Josh Holmes
  • From Developer to Business Owner roundtable with guest Nick Bradbury creator of HomeSite, TopStyle, and FeedDemon
  • 50+ break out sessions + Open Spaces (self-organizing sessions)
  • Grand Prize: VSTS 2008 Team Suite with MSDN Premium
  • Virtual sessions with Jeffery Richter and John Robbins

Space is limited so register today at CodeStock.org

Tuesday
Dec092008

Project Templates for SharePoint Development

I've had the privilege of working with an organization for almost two years now doing alot of SharePoint development. There's a team of approximately 75 developers that cover the gamut of skill sets and experiences, most of whom are working, to some degree, with C# and SharePoint development. One of the things that has come up repeatedly, is "how do I get started"? or "what project template should I be using"? These are good questions without a completely clear answer. This post (and hopefully some following) are intended to discuss what we are using, how it evolves, what options we discarded, and why. I spent last Friday teaching a class attempting to bring our team up to speed as to how to structure their SharePoint solutions/projects in VS and get them integrated with Team Build and packaged for deployment in our organization. As the day wore on, I realized how "janky" the "elegant" solution I had been using felt to someone new to the problem set. The supposed elegance was simply relative to the pain I had been experiencing doing it the "old way"... there has to be a better answer for the causal SharePoint developer.

I should stop here to add a caveat that prior to this assignment I spend a year or so (on and off) working on a custom VSIP toolkit for Visual Studio that included custom project and item templates as well as menu items, dockable tool windows, custom build tools, etc. so I'm a bit biased towards using the built-in extensibility hooks for Visual Studio (especially since its gotten so much easier with the 2008 release).

A year and a half or so ago we started by looking at the WSS Extensions for Visual Studio.. these were interesting and "felt" like the right answer because "they were from Microsoft... certainly they must be the best approach". While this sounded good (and in theory should have worked out) we ended up with a handful of issues... the first being their very slow support for VS 2008. Secondly, we often found a webpart project that suddenly stopped working (i.e. F5 deploying) and couldn't figure out how to get it working again... there seemed to be a bit too much "magic" going on behind the scenes. Also, It was completely unclear how one would take the resultant project and integrate it into a build system (i.e. Team Build). I'm sure it is possible, but it didn't seem to add much value beyond the initial development.

We then looked at STSDev (codeplex.com/stsdev). This is an interesting project that is *almost* my silver bullet. I like the way the template projects are setup, the layout, and the work that the post-build events work (automatically maintaining the ddf and manifest files as well as building the wsp). I have a handful of gripes with how they layout the project structure (no root folder for the solution) and the variables they use (or don't) for certain things. My biggest gripe is that I'm left wondering why they didn't leverage the existing, built-in templating features for Visual Studio (i.e. why can't I go File --> Add New --> web Part). Why should I have to train developers on yet another paradigm for creating their projects? Is their launcher really any better? I think not.  That being said, to this day, this is still the mechanism we are using for the majority of our work, but my dissatisfaction with the tool is the driver for this post and quest for a better end-to-end solution.

Because many of our developers were building webparts based on the SmartPart, we found ourselves looking at the SmartTemplates project. There was some very interesting things learned from the way in which Jan implemented this, but still some difficulties presented themselves when we tried to look at this tool relative to the larger problem of our entire SharePoint development environment (webparts, "standard" features such as menu items or application pages, smart parts, and Team Build).

While at PDC, I found myself talking with the Blueprint guys (http://codeplex.com/blueprints). Near as I can tell this is the successor to the GAX tools and looks to be very interesting. I spent part of yesterday afternoon studying the approach and found some very nice features (i.e. ability to update/maintain the platform via an RSS subscription). Unfortunately, the platform is still in beta and, at least in my testing, doesn't feel ready for primetime... maybe in a few months...

So, today I'm going to start out very basic and investigate simply building a custom project template that uses the built-in T4 templating features of VS. The objective is to have a project template that a developer can click on that will create a web application project, configured for development of ascx controls as smart-parts, along with a folder structure similar to what STSDev gives you supporting the build and auto generation of wsp files, as well as preparing the project for Team Build. 

Wednesday
Nov262008

.NET is a Smorgasbord?

Like many other .NET devs I often find myself expecting to be current in all of the existing and up-coming tools/technologies in the Microsoft/.NET platform. Frankly, I don't know how that is possible, especially with the pace at which MSFT (not to mention the surrounding ecosystem) is releasing tools and platforms. Over the past few years, my approach has been to know "enough" about the various tools/technologies so that I can be conversant, and also know when a particular toolset applies to my current project, thereby warranting a "deeper" dive into that area. Such has been the case for me with WPF and WCF (much of my work over the past while has been in the SharePoint/web space meaning WPF - until Silverlight - didn't have much of a play and we hadn't yet seen a need to switch from standard ASMX for our services). They fell into the bucket of tools I had seen while walking along the smorgasbord, but I simply hadn't decided I needed to consume them yet.

Scott Hansleman describes the .NET Framework and the MSFT tool suite as making it easy to "fall into success" (I'm sure I'm not quoting him correctly, but the idea is the same). Essentially, the tool set, while robust and quite capable, is approachable and relatively easy to simply build something. Especially when you compare it to other languages such as C++ -- in C#/.NET it is relatively easy to build "okay" code, and not that hard to build good code and almost (yes, there are plenty of exceptions) hard to write *bad* code. It is much easier (at least in my opinion) to write bad C/C++ code and much harder to write good C/C++ .code. I agree with him 100% - once you have a core competency on the platform, picking up the basics of the "new" stuff becomes almost trivial

I was recently working on a project (someone else did most of the coding - I did some of the design and proof-of-concept work) and I was able to see this in action. We were building a security-focused app, being deployed to a mixed environment of XP and Vista machines, and we had a 6-7 week window to build it, test it, and have it deployed. We ended up building a Windows Service that hosted a WCF service, a desktop application using WPF, a webpart for SharePoint and an IIS-hosted WCF service. We made heavy use of the cryptography libraries which, oddly (to me) were one of the areas that the other developer had prior experience with, however neither he nor I had done any real work with WCF and WPF. The technologies offered us quite a bit as far as functionality and form, even for two guys who weren't "experts" in them - that's where the "magic" lies - I'm reasonably comfortable with the MSFT dev stack, and I'm handed two completely new-to-me technologies, and with a relatively small amount of effort, I'm able to use them in my application and reap the benefits they bring. Now, certainly there's quite a bit more functionality that WPF/WCF bring to the table than what we used or "grok'd" during this project, but it did what we needed to and quickly - making me want to dig further into those technologies and to use them for other projects.

Friday
Sep242004

.NET Framework 1.1 sp1 and MPS - the real story

I've been contacted recently by a number of people regarding a recent scare about installing the service pack 1 for the .NET framework 1.1 on a system running MPS.  This issue has been fueled by the fact that Ensim had released a concern about the patch for their customers, and there have been a number of people reporting problems using the Configuration Wizard for MPS with the service pack.  So, let's get the facts out.

 

The Facts

Ensim Unify: As of the writing of this blog post (9/29/04), Ensim has issued a warning against installing the service pack on boxes running their Unify product (see this release here: http://kbold.ensim.com/TWKB/ViewCase.asp?QSRuleID=1039

).  This is an issue with their software that they are actively working on addressing.

 

Microsoft for Solution for Windows Based Hosting v2.5 with Hosted Exchange 2003:  The *only* issue with the service pack and the Microsoft solution is the configuration wizard.  This wizard is only used during setup, so if your environment is already set up, you have no worries.  For those of you who are needing to install the product, let me take a minute to explain the work around….

 

There is a small issue in the Configurator.exe.config file that was ignored by the .NET framework prior to SP1.  After you install SP1, the framework does a validation check on this configuration file as the application loads.  Because of this issue, you receive an error and the application closes.  The work-around is to remove the configuration file (simply delete it - by default it installs to C:\Program Files\Microsoft Hosting\Provisioning\ConfigurationWizard) and re-run the application.  I know that this seems odd, but it should resolve the problem.  I've spoken with the team at Microsoft, and they are working to release an "official" patched version that will eliminate the issue and should be available soon. 

 

The net-net is that MPS and the Windows solution runs without issue with the service pack installed and none of the providers are demonstrating any problems.

 

Support links:

http://groups.msn.com/provisioning

http://www.asp.net/Forums/ShowForum.aspx?tabindex=1&ForumID=167

Wednesday
May262004

.NET-based dac and role security

I'm continuing to work on a .NET version of the DAC (Delegated Administration Console) - essentially a UI front-end for the Microsoft provisioning System and specifically Hosted Exchange 2003.1... I've been learning a number of things and experimenting with some very interesting (at least to me) technologies.  I thought I'd share a little here and maybe post some more detail on each of these items over the next couple of weeks...

Themes/Skins
One thing I'm very interested in for this project is the ability to change the look/feel of the web site based on the user who signed in.  This should be controlled by the parent reseller for the user allowing the resellers to “White label“ the hosted service.  Whidbey has some very interesting support along this line, but the requirement for this project is to use ASP.NET 1.1, so I cannot utilize those features.  I found an interesting article written by Dino Espositio in the June ed. of MSDN magazine.  this is the second of two articles on the topic... the article in the May ed. was interesting, but not really useable, esp. compared to the enhancements made and presented in the June article.  This article really stretched my outlook with respect to using asp.net and how the underlying framework functions.  In my opinion, this is a good coding exercise for any advanced asp.net dev to help them think “outside the box“ on their projects.

Web Layout (a.k.a. Master Pages)
This topic seems to garner a great deal of interest and comments throughout the ASP.NET development community.  We all know that Whidbey is coming with all sorts of wonderful things for this topic, but that is little help to those of us who have customer deliverables in the next 12 months (or however long until Whidbey actually ships).  There are a ton of different ways to accomplish this, all with their pros and cons.  The most interesting option I've seen is provided by Paul Wilson (http://authors.aspalliance.com/PaulWilson/Articles/?id=14.  This approach is an extended/improved version of a sample provided to the asp.net web site by Rob Howard (MS) and is similar in some ways to what we have seen in Whidbey.  It may not suit your needs, but if this topic is something you are interested in, this approach is definitely worth the review.  I felt that the article text didn't do the best job of explaining what was actually happening (may have just been me) but once I converted the sample code to C# (my way of studying the code) and was able to get it working in my own site, it was very clear and easy to use.

Role-Based Controls
One of the most interesting (in my opinion) things that we accomplished in the ASP-based version of the DAC was to selectively hide/show/modify the UI and controls based on the assigned role of the currently logged on user.  In the ASP version of the DAC, this is handed via a combination of xml definition files that contain the control definitions and “acl” definitions and an ASP library called UIFramework.asp.  For this project i was looking for a more elegant way to store this information and a way to locate the role information as close to the control in question as possible.  My current approach is to create a library of web controls that inherit directly from the corresponding “official” control yet implement a set of properties extended for the UI options.  I'm overriding the OnPreRender method and planning on controlling the state of the control (i.e. visible = t/f and enabled = t/f) at this level.  I've not completely fleshed this out nor tested it in conjunction with the other items listed above, so we will see how well it does/doesn't work... more on this topic later.