Archive for .NET
CodeCamp NYC 2011.1 – Country Mouse in the City
Posted by: | CommentsSo I grew up in the small town of Fort Dodge Iowa, and let me tell you – I never expected to be walking around New York City having a great time. But, I knew any community that has Rachel Appel hanging around all the time would be at the very least uniquely fun, and most likely a great event. Let me tell you, it didn’t disappoint! It was great to walk around NYC and discover everything from clean cabs (seriously – and you could play football in the back of those things) to a bagpiper on Union Square to this thing:
Believe it or not, it’s registered as both a plane and a car. I wouldn’t want to bring either into the city!
I had a packed group for my presentation, so if you skipped out on the full room (I’m lookin’ at you, Gary!) here are the slides:
You can also find them on the CodeCampNYC site.
Enabling JSON Compression (and Gibraltar) in Windows Azure
Posted by: | CommentsA friend of mine posted to Twitter a bit ago that he was having trouble dealing with HttpCompression on Windows Azure. Specifically, only certain default MimeTypes were being compressed (like ASPX and CSS), while other important ones like JSON and SOAP were not.
During another Azure project, I also ran into an issue where logins stopped working after upgrading to Azure OS 2.X Azure SDK 1.3. It turns out that there is a bug in that release that doesn’t allow configuration inheritance for the MachineKey, and the workaround was to manipulate the server configuration in the RoleEntryPoint.
Since I’m already having to manipulate the server config to synchronize the MachineKey settings, I thought I’d whip up some code real quick to solve this problem during the same process, using the httpConpression topic on IIS.net as a guide.
If you don’t already have a RoleEntryPoint in your app… well, you should. Copy the code below into a new class file in your main application, and add a reference to Microsoft.Web.Administration.dll, as specified here. You’ll also notice Gibraltar-specific code peppered throughout… this is all that you need to get Gibraltar working on Windows Azure (as long as you’re also using the tip from my previous post as well).
(The code is long, and it’s in VB… because that’s the language this particular app was in. If you need it converted to C#, you can do so here.
UPDATE: My colleage Kendall pointed out that the role event handlers should be declared at the very beginning, and that, even though the RoleInstance’s OnStart event is called on a separate thread from the main app, it should still run the WarmUp loop on a separate thread, so that the function can return MyBase.OnStart() and exit properly. Good call.
Imports System.Linq
Imports Microsoft.WindowsAzure.Diagnostics
Imports Microsoft.WindowsAzure.ServiceRuntime
Imports Microsoft.Web.Administration
Imports System.Threading
Namespace Fon.Apps
Public Class WebRole Inherits RoleEntryPoint
Public Overrides Function OnStart() As Boolean
' For information on handling configuration changes
' see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
AddHandler RoleEnvironment.Changing, AddressOf RoleEnvironment_Changing
AddHandler RoleEnvironment.Stopping, AddressOf RoleEnvironment_Stopping
Gibraltar.Agent.Log.SendSessionsOnExit = True
Using server As New ServerManager()
'Cycle through the sites and set the MachineKey for each one.
For Each site In server.Sites
Dim siteConfig = site.GetWebConfiguration()
'Get the appSettings section
Dim appSettings = siteConfig.GetSection("appSettings").GetCollection().ToDictionary(Function(e) DirectCast(e("key"), String), Function(e) DirectCast(e("value"), String))
'Reconfigure the machine key
Dim machineKeySection = siteConfig.GetSection("system.web/machineKey")
machineKeySection.SetAttributeValue("validationKey", appSettings("validationKey"))
machineKeySection.SetAttributeValue("validation", appSettings("validation"))
machineKeySection.SetAttributeValue("decryptionKey", appSettings("decryptionKey"))
machineKeySection.SetAttributeValue("decryption", appSettings("decryption"))
Next
'Turn on compression for JSON and SOAP.
Dim config As Configuration = server.GetApplicationHostConfiguration()
Dim httpCompressionSection As ConfigurationSection = config.GetSection("system.webServer/httpCompression")
Dim dynamicTypesCollection As ConfigurationElementCollection = httpCompressionSection.GetCollection("dynamicTypes")
Dim e1 As ConfigurationElement = dynamicTypesCollection.CreateElement("add")
e1("mimeType") = "application/json"
e1("enabled") = True
dynamicTypesCollection.AddAt(0, e1)
Dim e2 As ConfigurationElement = dynamicTypesCollection.CreateElement("add")
e2("mimeType") = "application/json;charset=utf-8"
e2("enabled") = True
dynamicTypesCollection.AddAt(0, e2)
Dim e3 As ConfigurationElement = dynamicTypesCollection.CreateElement("add")
e3("mimeType") = "application/soap+xml"
e3("enabled") = True
dynamicTypesCollection.AddAt(0, e3)
server.CommitChanges()
End Using
'Poor man's Application Warm-up here
Tasks.Task.Factory.StartNew(Sub()
Try
While (True)
Trace.WriteLine("Warming up web site...")
Dim webClient As New Net.WebClient()
webClient.DownloadString("http://mysite.com/WarmUp.ashx?WarmUp=True")
Thread.Sleep(TimeSpan.FromMinutes(9))
End While
Catch ex As Exception
Gibraltar.Agent.Log.RecordException(ex, "WindowsAzure.WebRole.Startup", True)
End Try
End Sub)
Return MyBase.OnStart()
End Function
Private Sub RoleEnvironment_Stopping(sender As Object, e As RoleEnvironmentStoppingEventArgs)
Gibraltar.Agent.Log.EndSession(Gibraltar.Agent.SessionStatus.Normal, "Azure's configuration settings have changed.")
End Sub
Private Sub RoleEnvironment_Changing(sender As Object, e As RoleEnvironmentChangingEventArgs)
' If a configuration setting is changing
If e.Changes.Any(Function(change) TypeOf change Is RoleEnvironmentConfigurationSettingChange) Then
' Set e.Cancel to true to restart this role instance
Gibraltar.Agent.Log.EndSession(Gibraltar.Agent.SessionStatus.Normal, "Azure's configuration settings have changed.")
e.Cancel = True
End If
End Sub
End Class
End Namespace
You might have noticed the While loop that cycles every 9 minutes and makes a request to a specific website. Though the actual site details have been abstracted out, this is a trick that I use to keep my application “warmed up,” and is a variation on the technique used by Christian Weyer.
For the MachineKey part, you’ll also need to add the following entries to the appSettings section of each of the web.configs in your Role, being sure to replace your values where appropriate:
<add key="decryption" value="Auto" /> <add key="decryptionKey" value="YOURVALUEHERE" /> <add key="validation" value="SHA1" /> <add key="validationKey" value="YOURVALUEHERE" />
You’ll also notice that it’s also pretty easy to add additional MimeTypes to compress. Just continue to copy the pattern for any of the items you think are missing. Be sure not to add ones that don’t already exist, or you’ll likely crash your role.
Anyways, I I hope that helps some of you that are trying to resolve various Azure issues.
Have You Sampled Our Code Samples Yet?
Posted by: | CommentsOne of the great things about coming to work for Gibraltar is learning about all of these things that I didn’t know the product could do. For example, the other day, I was asked in one of our Live Support chats about how to see the details of a web site session in progress.
Gibraltar collects a wealth of information about your running website. However, by default, you can’t analyze the data until the web server process completes. I knew that live monitoring is one of the killer features slated for Gibraltar 3.0, but I didn’t realize that there are also very simple, workable ways to get Gibraltar data anytime you need it within the current Gibraltar 2.5 release.
As a former Gibraltar customer, when I wanted to get this data in the past, I simply recycled the AppDomain myself. I had Gibraltar configured to “autoSendSessions”, so whenever I recycled the AppPool, I’d automatically receive the latest logs. I realize that is not the best answer for a number of reasons, but it is what worked for me, so I passed that suggesion to the customer.
A little later, our fearless leader Jay messaged me and asked why I hadn’t sent him the link to the Code Samples page, which shows how to make Gibraltar immediately send the package for the current session whenever an error is logged. Feeling a little sheepish, I admitted “Because I didn’t know we had that feature.”
It turns out, we have some pretty cool samples that do a lot of very useful things. If you haven’t had a chance to check them out yet, you should. This also got me thinking about some ways we can make our samples more visible and accessible. Stay tuned for some cool web site updates in the coming weeks.
Before I go, I wanted to suggest a slight tweak to the “Submitting Sessions on Error” sample I just pointed you to. In .NET 3.5 and later (4.0 for you VBers out there), you can take advantage of Lambda Expressions to simplify this call a little bit. The version I use looks like this:
protected void Application_Start()
{
Log.MessageAlert += (sender, e) =>
{
if (e.TopSeverity <= LogMessageSeverity.Error)
{
e.SendSession = true;
e.MinimumDelay = new TimeSpan(0, 5, 0);
}
};
}
Or for the VB folk:
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) AddHandler Log.MessageAlert, Sub(sender1 As Object, e1 As LogMessageAlertEventArgs) If (e1.TopSeverity <= LogMessageSeverity.Error) Then e1.SendSession = True e1.MinimumDelay = New TimeSpan(0, 5, 0) End If End Sub End Sub
This is simply some neat syntactical sugar that IMO makes your code a bit easier to read. Instead of having to follow the event handler to another method, you can see how the event is handled right there, without another method signature clogging up your code. Under the covers, the compiler will create the signature as an anonymous method, and sort everything out for you. Neat, huh?
I learn something new every day around here. Hope this little tidbit makes you more productive.
Philly Code Camp 2010.2 Presentations & Fun
Posted by: | Comments
Thanks to everyone for coming to my sessions and the organizers for making the event run so well. The facility was great and it’s really quite remarkable that the community can have such a strong one day training event without having to charge participants. Microsoft was there to help out, but it was clearly a training event for the community not a Microsoft press event, exactly as it should be.
We had fun talking with the other vendors at the show, most notably Component One and the folks from CapTech. This is the first time we’ve had a vendor booth at an event like this, so in many ways it was a dry run to get the hang of what it’s like. We gave away a full copy of Gibraltar Analyst as well as a year’s subscription to Hub at the conference, and got to talk with a lot of people about both Gibraltar and VistaDB. We got some great real world examples of where VistaDB fits, which is a big help as we work on the marketing for that going forward.
I presented two sessions -
A Year in the Life of an ISV
If you’re thinking about what it’d be like to ditch your corporate development job or consultant gig and strike to create & market your own product (Or you’re a consultancy looking to create a product to diversify) this presentation shows what to expect on the path from shipping your first version to business success.
This one’s always a little risky at a code camp because, well… there’s no code. But, with the incredible diversity of tracks that were available at Philly Code Camp (13 tracks, over 60 sessions…) I think it’s also good to be able to “take a break”. Next time I might go for the last session of the day to maximize the value of that.
Designing APIs for Others
I covered a range of real world lessons about commercial API development emphasizing the differences between in-house & internal development and great, reusable commercial libraries.
I got some great feedback on this talk, particularly on an example that broke my own rule about samples: I tried to over-simplify it and instead created a “not best practice” sample. I’ll fix that for next time!
If you saw either presentation, please be sure to fill out the conference evaluation and I’d love to hear your feedback – drop it in the comments below or send it to me directly at kendall.miller@gibraltarsoftware.com.
If you’d be interested in having us come talk at your code camp, .NET Users Group, or event – please reach out and let us know. We’re always looking for new & better ways to engage with the community.


