Azure Table Storage Exceptions with Multiple Table Entity Schemas

 

I’ve been messing with Azure Table Storage recently and needed to create a somewhat nontrivial data model to try some things. 

This data model includes patients, patient addresses (email, IM, postal, phone, etc.) and patient events.  I also wanted to store all of this data in the same table so I had table entities with differing schemas in the same table.

I then wrote some code to created an array of patients and for each patient I added the patient record and a random number of different patient addresses to the table. 

The more I work with Windows Azure the more I come to the conclusion that debugging Windows Azure code is like a Doctor treating a patient, i.e. make random changes and see if that fixes the problem.  Trying to figure out what the problem is from the exception information is like looking in a crystal ball in that it just doesn’t show anything other than what you can imagine.

Executing the code results in what appears to be one of the most common exceptions there is when working with Windows Azure:

{Microsoft.WindowsAzure.StorageClient.StorageExtendedErrorInformation}
    AdditionalDetails: null
    ErrorCode: "InvalidInput"
    ErrorMessage: "0:One of the request inputs is not valid."

 

So my next issue is that I had added multiple records so which one was causing the problem?  To figure that out you need to enumerate the DataServiceRequestException.Response property.  You get an IEnumerable<ChangeOperationResponse> collection from this property.  From my experience so far there only ever appears to ever be one entity in this collection no matter how many records you create that would have had problems.  What you look for is a header by the name of “Content-ID” on the OperationResponse.  The value is the 1 based index of the records that were added before calling TableContext.SaveChangesWithRetries(SaveChangesOptions.Batch).

You can see this a lot better if you use Fiddler to view the input/output of the batch request.  See http://learningbyfailing.com/2009/12/using-fiddler-with-azure-devstorage/ to see how to get Fiddler to display the output.

In my case it kept pointing to the second record that I added (the first was the patient record and the second was an address record).  If I saved the patient record by itself it worked and if in a separate batch I saved the address records it worked.  So in spite of the exception pretty much not telling me what the problem was I came to the conclusion that I can’t mix table entity schemas in a single batch.  Apparently this is a restriction for development storage but will work when using cloud storage.

It’s too bad the exception didn’t tell me this.

Remember that Azure Tables have limited property datatype support

Recently I threw some code together to add objects into an Azure table.  I used the class:

	[DataServiceKey("PartitionKey", "RowKey")]
	public class OrderMessage : TableServiceEntity
	{
		public DateTime OrderDate { get; set; }
		public string CustomerName { get; set; }
		public string CreditCard { get; set; }
		public int Quantity { get; set; }
		public decimal CostEach { get; set; }
	}

Upon adding the data to the table using:

	TableServiceContext tableContext = connection.TableClient.GetDataServiceContext();
	tableContext.AddObject(connection.OrderTableName, message);
	DataServiceResponse response = tableContext.SaveChangesWithRetries();

I received the error:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">

<code>InvalidInput</code>

<message xml:lang="en-US">One of the request inputs is not valid.</message>

</error>

 

After wasting some time looking at help and Googling I was skimming across some documentation on tables and it happened to list the supported property types for Azure tables.  I knew that they had limited support but not till I looked at that list did it occur to me that I was using the unsupported datatype ‘decimal’.  Modifying the class so that CostEach was of type ‘double’ resolved my problem. 

It sure would be nice if the error was a little more explicit.  I’m sure that somewhere in the Azure code it knows what happened.  I also find it interesting that rather than returning information in the DataServiceResponse it throws an exception.  I don’t see this ability to throw exceptions in the documentation and in fact the documentation says that the return value is:

A DataServiceResponse that contains status, headers, and errors that result from the call to SaveChanges.

On well I guess somebody kinda forgot to update their XML comments on the method with:

/// <exception cref="System.Data.Services.Client.DataServiceClientException">A stealth exception that we won't tell anybody about</exception>

More than once I’ve seen a reminder on blogs to make sure you only use the supported data types on your table entities.   Here’s another reminder for you and *bonk* me!

Windows Azure error “There was an error attaching the debugger to the IIS worker process for URL ‘http://127.255.0.0:82/’…”

Since I last rebuilt my development machine I haven’t had a need to even look at web development let alone Windows Azure.  The last time I had “opportunity” to develop anything using Windows Azure was with version 1.3.  At the time version 1.4 was still in beta and I couldn’t seem to successfully install it.

Lucky me I was added to a project using Windows Azure so I installed version 1.6 along with the Windows Azure Platform Training Kit – November Update and decided to make a quick run through some of the training kit to see how things worked.

Much to my chagrin attempting to run the training projects only ever resulted in the dialog:

image

The first thing that popped out at me was the IP address ‘127.255.0.0’.  I immediately proceeded to look at project properties to figure out where this came from to no avail.  I then unloaded the projects and looked through the raw project and solution files to no avail.  Attempting to ping the address did succeed so I looked through my hosts file in ‘%windir%\System32\drivers\etc’.  Nope it wasn’t there either. 

Searching the Internet (hmmm, I wonder if the term ‘Binging’ will be added to the dictionary?) on the error message gave me a whole lot of nothing.  Refining my search to just the IP address sent me off on a tangent for blogs on Windows Azure v1.5 about the need to add entries to the hosts file, although they were helpful in educating me about what in the world the IP address was.  For more information on that see http://blogs.msdn.com/b/avkashchauhan/archive/2011/09/16/whats-new-in-windows-azure-sdk-1-5-each-instance-in-any-role-gets-its-own-ip-address-to-match-compute-emulator-close-the-cloud-environment.aspx.

Finally *bonk* I got the idea to look in the Windows Event log.  It should have been the first place I looked but I guess I hadn’t drank enough coffee yet to think straight.

I found two errors:

ISAPI Filter ‘C:\Windows\Microsoft.NET\Framework\v4.0.30319\\aspnet_filter.dll’ could not be loaded due to a configuration problem. The current configuration only supports loading images built for a AMD64 processor architecture. The data field contains the error number. To learn more about this issue, including how to troubleshooting this kind of processor architecture mismatch error, see http://go.microsoft.com/fwlink/?LinkId=29349.

and

Could not load all ISAPI filters for site ‘DEPLOYMENT16(11).WINDOWSAZUREPROJECT1.GUESTBOOK_WEBROLE_IN_0_WEB’.  Therefore site startup aborted.

That certainly gave me a good clue.  Why I need ‘Enable 32-bit applications’ on the application pool I have no idea since I’m compiling as ‘Any CPU’.  Compiling as x64 results in the same errors and compiling as x86 fails because I’m running on an x64 box and results in the dialog:

image

Every time the computer server starts it creates a new application pool with ‘Enable 32-bit applications’ set to false.  When the compute server shuts down it removes the application pool so manually resetting this value doesn’t help.  Searching around found http://blogs.msdn.com/b/zxue/archive/2011/10/31/enabling-support-for-32-bit-iis-applications-in-windows-azure.aspx.  Adding the startup task to set the IIS default to allow 32-bit applications solved my problems.  It really only needs to be run once but I just leave it in the project just in case.

Using Compiled Resources and Generating Debug Info with MASM32

I had been using the MASM32 SDK to get familiar with Microsoft Assembly.  I thought I’d just share a couple basic things that helped me in the process.

Using Compiled Resources

The MASM editor that is installed from the SDK is the ‘Small Memory Footprint Editor Quick Editor’.  Creating, compiling, linking and running MASM source code through this editor is a simple process.  It definitely makes you miss some of the tools that Visual Studio provides though.  One of which is the resource editor.  The good news is that you can create resource files (.rc) in a Visual Studio C++ project, munge them a bit (remove the C++ ishness like included .h files, embed the #defines into the .rc rather than have a separate .h file and such things as that) and use them in the compilation process to produce your final binary.

To start the process you need to use a menu option in the editor to generate a ‘makeit.bat’ file.  This file compiles the assembler files, compiles the .rc file and links everything for you.  To generate this file use the editor menu option:

Script –> Create EXE makeit.bat

This assumes of course that you are creating an .exe type binary.  If you’re creating something else then use the appropriate menu option.  The file assumes that your .rc file is named rsrc.rc.  So after you create your .rc file in Visual Studio then just copy it into your MASM project directory as the file name rsrc.rc.

The ‘makeit.bat’ file that is created looks like:

image

Generating Debug Info and Other Stuff

To cause MASM32 to also generate debug information when it compiles and links I simply edited this file and added command line parameters to both the compile (‘\masm32\bin\ml’ command line [/Zi /Zd /Zf]) and link step (‘mask32\bin\Link’ command line [/DEBUG /DEBUGTYPE:CV]) steps.  Note that I also added command-line parameters to the compile command to generate browse information (/FR), a map file (/Fm), an assembled code listing (/Fl) and generate warnings (/W3).

image

Now when I compile I get my assembled code listing (.lst), browse information (.sbr) and debug information (.pdb) files.

image

Configuring Visual Studio 2010 for Assembly Development

In my last blog entry “Assembling Old-School Skills” I bemoaned the fact (or what I thought the fact was) that Visual Studio 2010 ended up just being a glorified text editor when doing MASM development.

Buzzzz! Wrong!

You can in fact configure Visual Studio 2010 for use in MASM Assembly development.  The following list of steps are what is needed to accomplish this:

  • Create a Visual C++ “Win32 Console Application” project

image

  • Press ‘Next’, uncheck ‘Precompiled header’ and press ‘Finish’
  • Choose ‘Build Customizations…’ from the projects context menu and press ‘OK’

image

  • Delete all .cpp and .h files from the project
  • Add the file ‘Main.asm’ under ‘Source Files’
  • Add the following text from the tutorial at http://win32assembly.online.fr/tut2.html to ‘Main.asm’

        .386
        .model flat,stdcall
        option casemap:none

        include windows.inc
        include kernel32.inc
        includelib kernel32.lib
        include user32.inc
        includelib user32.lib

        .data
        MsgBoxCaption db "Iczelion Tutorial No.2",0
        MsgBoxText db "Win32 Assembly is Great!",0

        .code
        start:
        invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK
        invoke ExitProcess, NULL
        end start
  • Now when you look at the project properties you will find ‘Microsoft Macro Assembler’ under the ‘Configuration Properties’

image

  • In the project properties edit the following:
    • Linker –> General
      • Additional Library Directories
    • Microsoft Macro Assembler
      • General
        • Include Paths – Add the path to your .inc files.  I’m using the ones from the MASM32 SDK.
      • Listing File
        • Assembled Code Listing File – Set to something similar to: $(IntDir)%(FileName).lst
  • Ignore the auto-correct squiggly at the beginning for the ‘PCH warning’.  It seems to be something to do with Visual Studio 2010 SP1 ‘PCH warning after installing SP1
  • Compile and run your code

Assembling Old-School Skills

I’ve programmed in IBM 360 and VAX Assembly before but I have been working in a Microsoft Windows environment on an Intel x86/x64 hardware platform for quite a while.  That little reminder in the back of my head has kept popping up saying it was time to learn Intel Assembler but the auto-click to “close the annoying popups” has until recently triumphed.  I finally decided to go for it.  Since I want to target Microsoft Windows on an Intel platform I figured I’d go for the MASM Assembler.

I learn pretty well through reading books so I opened up Amazon to search around for something that would help.  Much to my chagrin authors either don’t target Windows, don’t target a flat memory model (come on! it’s been a while since we were all working on 8086 processors guys), don’t target MASM or haven’t written a book on Assembly in the current century.

The best resources I’ve found so far are Internet resources.  Following are some good ones I’ve found so far:

You’d think that the MASM development environment would be integrated somehow into the Visual Studio environment but I guess it’s so rare for somebody to write anything in Assembly they don’t feel like putting in the time to develop and maintain that part of Visual Studio.  You can get an add-in for Visual Studio 2010 that does highlighting for Assembler called ‘AsmHighlighter’ but you’ll just be in a text editor not a development environment.

A very old-school (it makes you think of DOS editors) x86 development environment is installed as part of running the ‘Install.exe’ found on the ‘MASM32 SDK’ link above.  Before running the ‘Install.exe’ note all the warnings about AntiVirus scanners.  Norton Anti-Virus no longer complains, not sure about other scanners.

The x64 Assembler ML64.EXE is part of the Windows Driver Kit but note that it’s the Assembler, not a development environment.  I guess that’s why we have the very expensive text editor named ‘Visual Studio’ and the venerable notepad.

So, anyway, once you get into using Macro Assemblers you find that the “Macro” part of the Assembler means that it seems like you’re programming in a combination high-level/low-level programming language.  Some of the very repetitive sequences of instructions like setting up and tearing down call stacks (‘invoke’ keyword) and flow control statements (.IF, .ELSEIF, .WHILE, etc) are provided.  The rest of it though is a good ole Win32 programming (when is the last time you used RegisterClassEx & CreateWindowEx?) and lots and lots of push/pop/mov commands.

My original motivation for learning Intel Assembly was to be better able to diagnose program dumps and I know learning the programming methodology needed to write Windows programs in MASM is a necessary start in that directory but looking at the disassembled program code:

image

is a whole lot different than looking at:

image

So my next thought was that there has to be a good disassembler out there for Intel x86 Assembly.  After searching for a while and finding a number of virus delivery systems masquerading as disassemblers I found a very good tool named IDA at http://www.hex-rays.com/.  There is a freeware version of the tool called ‘IDA Freeware’ at http://www.hex-rays.com/products/ida/support/download_freeware.shtml.  The freeware version has limitations of course so I figured I’ll just go ahead and buy the professional version.  After catching my breath at the price of $1,059.00 I just added that software to my “I hope I have a rich uncle and he buys me this” list.  So for now I’m sticking with the freeware version Open-mouthed smile

Using ‘IDA Freeware’ for the same binary I get:

image

I have a long long way to go on getting comfortable with Intel Assembly but at least I’ve made that first step.

Passing ListView.SelectedItems as a ContextMenu CommandParameter

I spent quite a while trying all of what I thought were the obvious methods of doing this and couldn’t get anything to work.  Then I stumbled on a Blog by Richard Griffin at http://consultingblogs.emc.com/richardgriffin/archive/2007/02/23/WPF-Commands-a-scenic-tour-part-I.aspx that pointed me in the right direction.

	<ContextMenu>
	  <MenuItem Header="Schema"
	    Command="{Binding ExportSchemaCommand}"
	    CommandParameter="{Binding Path=PlacementTarget.SelectedItems, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" />
	</ContextMenu>

Rather than trying to do something obvious like use RelativeSource or ElementName to find the BindingPath use the ContextMenu.PlacementTarget.

ListView.SelectedItems is of type System.Windows.Controls.SelectedItemCollection which is marked as Internal so in your command you have to cast it as its base class which is System.Collections.ObjectModel.ObservableCollection<object>.