July 30, 2008

Passing a Large Mapguide Selection XML to a New Window Using Dynamic Forms and Javascript

Filed under: Mapguide — Tags: , — Darrin Maidlow @ 11:22 pm

Everyone knows there is a , right?  Well ok, maybe you didn’t – but there is.  What that limit is depends on the browser.  There is a lot of conflicting information out there on the magical .  An RFC defines it, but no one really seems to pay attention to those anyhow.  (Are you listening Microsoft, of course you are! =]).  Anyhow, for IE, the query string length is usually around 2000 characters.

However, in most cases you’re better off using a form and posting your data up to the server side that way, as the limitations on data are so large you will likely not need to worry about them.  Sometimes, query strings can also show your users just a little too much information – though I’m by no means a proponent of "security through obscurity" hiding a little bit more from your users will keep the curious ones a little more in check =).

When working with / we need to grab some potentially massive XML strings from the MgMap object and pass these along to the server side for processing.  Take the selection XML from the MgMap object, even a single entity selection can use a significant portion of the characters available in the query string.  On top of that, passing this data via query string requires that the data be URL encoded, using even more of our precious query string characters.

Depending on the design of your application it may not always be feasible to define a hard coded form, or even a form defined server side using ASP.NET.  In some cases (you guessed it – my case) you may want to use javascript and do all the work on the client side to define a form and pass the data long that way.

Well you’re in luck, I found a pretty nice solution (WELL, at least I’m liking it  =]).   I’m kicking myself for not realizing this long ago, but oh well.  So the following javascript function demonstrates how to build, add, populate, and submit a form on the fly using some information from the MgMap object.

   1: function postData()   
   2: {   3: //get the map   
   3: mapObj = GetMap();   
   5: //define the new form   
   6: var newForm = document.createElement("form");   
   7: //set the method to POST - the opposite of query strings..   
   8: newForm.method="POST";  
   9:  //add the new form to the current document  
  10:  document.body.appendChild(newForm);  
  12:  //lets get some data and add it to the form  
  13:  AddFormElement(newForm, "MapName", oMap.GetMapName());  
  14:  AddFormElement(newForm, "SID", oMap.GetSessionId());  
  15:  //be sure you escape the selection XML - or you will get an error on post about a   
  16:  //"potentially dangerous form value".  Remember on the server side to Server.UrlDecode() it  
  17:  AddFormElement(newForm, "sel", escape(oMap.GetSelectionXML()));  
  19:  //lets create our new window  
  20:  var szTarget = "targetWin"  
  21:  newForm.target = szTarget;  
  22:  //set the name/path of the ASPX file you want to process your form with  
  23:  newForm.action = "/url_to_open/file.aspx"  
  25:  //open a new window to submit the form to.  Its a good idea to have a blank.htm so you don't get a file not found error  
  26:  var oWin = window.open("blank.htm",szTarget,'menubar=yes, resizable=yes,scrollbars=yes, status=no,toolbar=no,width=300, height=300');  
  28:  //give the window focus.  Users like this  
  29:  oWin.focus();  
  31:  //submit the form - it will now open in the new window  
  32:  newForm.submit();  
  33:  //remove the form from the document, we're done with it  
  34:  document.body.removeChild(newForm);  
  35:  }  
  37:  function AddFormElement(form, elementName, elementVal)  
  38:  {  
  39:      var newElement = document.createElement("<input name='" + elementName + "' type='hidden'/>");  
  40:      newElement.value = elementVal;  
  41:      form.appendChild(newElement);  
  42:      return form;  
  43:  }


On the server side, you can now access this data from ASP.NET using Request.Form, for example Request.Form("MapName") would give you the map name.  Don’t forget when retrieving the selection XML to run that through Server.UrlDecode, or HttpUtility.UrlDecode.

As usual, any comments, bugs, or rotten fruit – send em my way.  Enjoy!

Mapguide 2009 / OS 2.0 Get Selected Key Values VB.NET Example and the dreaded MgSelection.GenerateFilter Issue

Filed under: Mapguide — Tags: , — Darrin Maidlow @ 2:12 am

Tonight I came across the .  I had read about it, and made a mental note that one day it would be an issue.  That note wasn’t very good, and I completely forgot about it.   I was wrapping up the updates around the report this eve and fortunately I bothered to select the entire map and run through a report.

RADE Report - but what, only 20 records returned?

Report looked good.  The results were sorting, checkboxes working.   Wait a minute, I selected the entire map.  There should be more than twenty items returned.  So a quick search of my twelve thousand saved e-mails from the turned up what needed to be done.  Fortunately Autodesk added a GenerateFilters call to MgSelection.  This call returns an MgStringCollection of filters.

Basically the solution to this problem is to use GenerateFilters instead of GenerateFilter, and loop through the results.  Each time, appending the returned keys to the complete list.  For example:

   1: Public Shared Function GetSelectedKeysString(ByRef siteConn As MgSiteConnection, _
   2:     ByRef resSvc As MgResourceService, ByVal oMap As MgMap, ByVal SessionId As String, _
   3:     ByVal SelectionXML As String, ByVal layerResID As MgResourceIdentifier, _
   4:     ByVal keyFieldName As String) As String
   6:     Dim szKeys As String = ""
   7:     Dim oSel As New MgSelection(oMap)
   8:     oSel.FromXml(SelectionXML)
   9:     Dim curLay As MgLayerBase
  10:     'isolate the layer
  11:     For Each layerItem As MgLayerBase In oSel.GetLayers
  12:         If layerItem.Name = layerResID.Name Then
  13:             curLay = layerItem
  14:         End If
  15:     Next
  17:     Dim featSvc As MgFeatureService = siteConn.CreateService(MgServiceType.FeatureService)
  18:     Dim queryOptions As New MgFeatureQueryOptions
  19:     Dim featureClassName As String = curLay.GetFeatureClassName
  20:     'workaround using GenerateFilters and looping through the results as needed
  21:     Dim featureReader As MgFeatureReader
  22:     Dim filters As MgStringCollection = oSel.GenerateFilters(curLay, featureClassName, 20)
  23:     Dim filterCnt As Integer = 0
  24:     While filterCnt < filters.GetCount
  25:         queryOptions.SetFilter(filters.GetItem(filterCnt))
  26:         featureReader = featSvc.SelectFeatures(New MgResourceIdentifier(curLay.GetFeatureSourceId), featureClassName, queryOptions)
  27:         While featureReader.ReadNext
  28:             If szKeys = "" Then
  29:                 szKeys = ConvertPropertyToString(featureReader, keyFieldName)
  30:             Else
  31:                 szKeys &= "," & ConvertPropertyToString(featureReader, keyFieldName)
  32:             End If
  33:         End While
  34:         featureReader.Close()
  35:         featureReader.Dispose()
  36:         filterCnt += 1
  37:     End While
  38:     Return szKeys
  39: End Function


In this code, we get the selection from the MgMap object and then isolate the layer in question.  Then we generate the collection of filters and loop through them.  Each time, adding the appropriate value to the list of keys.  Note the use of ConverPropertyToString, this needs to be used to ensure that the various data types are converted over to string.

I’ve included this function as well as a couple other handy related ones in the attached zip file

.  If you’re looking for a C# example of how to use GenerateFilters one is provided in the .

After making these changes my reports now look all proper! hurray.  Maybe I can hit the sack now?  nahh.

RADE report - but this time everything looks ok 

July 19, 2008

RADE Milestone – Object Relational Mapping with NHibernate

Filed under: RADE — Tags: , — Darrin Maidlow @ 3:37 am

It’s 1:30AM, I guess it’s Saturday now. =)  I’ve been furiously pounding away for the past two weeks building a new for RADE 4.0.  Gotta love 12 – 18 hour days for two weeks (Good thing I love software development).  My wife is away for the week, so I can continue working these stupid hours for another week.  Anyhow I’ve chosen to proceed with for the time being.  with the looks really cool and I’ve used it for some small research/test projects recently, but with the lack of support for database other than SQL server – it’s not an option at this time.

NHibernate was a tough curve for me.  Initially, I started testing code generators.  After spending a significant amount of time reading, testing, and pulling out hair I came to the conclusion that .  From my experiences is probably the best code generator out there right now – but its still lacking in some areas.  More importantly however, I learned that code generation is not a good place to start when implementing NHibernate for the first time.  There is so much going on under the hood – in my opinion you need to start off doing a reasonable size project by hand.  Code generation has significant benefits, because the generated code is so similar with simple replacements it just makes a lot of sense once you wrap your head around what’s going on with NHibernate.

As per my when implementing nHibernate by hand, .  Just the other day I found a *great* ReSharper .  When editing NHibernate HBM XML files, it does a bunch of validation right in the editor.  Saves you a lot of time finding problems without having to actually run a unit test and debug sometimes cryptic error messages.

I bought a copy of NHibernate In Action.  I would recommend this book to you only if you have no experience, or understanding of Object Relational Mappers.  As the book stands right now, it’s not really a good developer reference and only covers really basic examples.  The documents that helped me the most to get everything up and running was .  The NHibernate documentation is pretty cryptic.  Don’t read this stuff 12 hours into your day.  No amount of RedBull will give you the focus needed to make sense of it.  In the first 8 hours of the day, its quite helpful.

I primarily work in VB.NET.  For this project however, I switched to C#.  Maybe now, the my colleagues at will stop giving me a hard time =).  Seriously though.  Examples are a LOT easier to come by in C#, probably 10:1.

Finally, get NUnit running.  I had a lot of problems using the built in Microsoft Test projects with NHibernate – so I’ll be sticking with NUnit. If you’ve never done unit testing (you know who you are) do it.  Particularly in this case – its crucial.  You (Again you know who you are =]) used to write simple winform apps, and put a bunch of buttons on them.  Don’t do that. 

So, if you are one of the RADE non-developer users and you read on this far.  Congrats.  This milestone will not directly help you with your use of RADE.  However, it’s a large step forward for the underlying architecture – and you will benefit from that. 

Well back to Visual Studio I go..

Technorati Tags: ,,,

July 14, 2008

ReSharper – A Class Creating Machine

Filed under: Development — Tags: — Darrin Maidlow @ 7:43 am

Recently, I purchased a copy of .  I’m not even going to pretend I’ve scratched the surface of what ReSharper can do, but I can assure you it’s a massive time saver when creating classes from scratch.  I’m furiously plugging away, implementing an ORM for RADE, and to do that I needed to create a lot of classes pretty much from scratch (oh, and do I have a few things to say about that, but that’s for another day).  Let’s look at a simple example.  To get things started, create a new class.  Select the folder in the solution explorer, and press Alt+Insert:

ReSharper Class Creation

Press enter and you are prompted for the class name.  So Visual Studio has this of course, but this is a small example of some of the time savings you can achieve.  Enter the class name and you start off with an empty class.  Next, lets define a couple of private members.   Let’s run with the following example.

   1: namespace RADE.BO.Domain
   2: {
   3:     public class SampleClass
   4:     {
   5:         private Int32 _ID;
   6:         private String _Description;
   7:         private Int64 _BiggerInt;
   8:     }
   9: }


Simple class.  Three member variables.  Here is where the big time savers come in.  Next, click Alt+Insert again and you will be prompted with the following options:

Some ReSharper Code Generation Tools

Choose Properties.  You will now be given the option to select one or many fields, set the access rights, read only and virtual properties as well a bunch of others. 

ReSharper Properties Generator

Execute that and all of your get/sets are defined.  My one complaint is that ReSharper is not maintaining the type on the properties.  My Int32′s become int, and Int64′s become long’s.  Apparently this is slated to be fixed.  

So yes, this sample class is tiny, but the time savings on larger classes, or projects full of classes are significant.  The last feature I’ve been using extensively in this project is the generate constructor tool.  Again, a form is displayed with the defined properties, select the ones you want and boom.  You can create half a dozen different constructors in seconds.  I’ve created a full object model on, roughly 20 different mildly complex objects in less than an hour, around midnight on a Sunday =)

Some of the other things ReSharper does is suggest code cleanup ideas by removing unused directives, easy execution of , improved code completion.  I encourage you to check it out, .

Technorati Tags:

July 11, 2008

ODAC/ODP.NET on Vista x64

Filed under: Oracle — Tags: , , , — Darrin Maidlow @ 7:11 am

Since moving to Vista x64 I’ve had a heck of a time with Oracle clients.  The one thing I could not get working until tonight was ODP with Visual Studio / .NET.  Finally I found a solution.

First, download and install . (Link requires registration)   This should get the 32bit stuff installed.   I’m still using an Oracle 10g R2 server.  You will likely need to grab a copy of the TNSnames.ora for your existing client folder and place it in the appropriate tree of the 11g product home.

This however is not enough to get .NET working with ODP.  Go to the folder where you extracted the zip.  We need to find the Oracle.DataAccess.dll.  This can be found in the file named filegroup4.jar, in the stage\components\oracle.ntoledb.odp_net_2.  Winrar will open .jar files if needed.  Extract the Oracle.DataAscess.dll file.

For now, I’ve put a copy of this file in my projects lib folder.  I then added a reference directly to this file from all projects that need ODP access. 

Keep in mind – before you ship you may want to remove this reference and ensure that the .DLL file doesn’t get included in your build.  This should get your Vista x64 box developing with ODP.

To Oracle – come on guys.  Give us some Vista x64 love!

Technorati Tags: ,,,,

July 7, 2008

Mapguide Enterprise – Cannot Select Items in DWF and AJAX viewer – Again

Filed under: Mapguide — Tags: , , — Darrin Maidlow @ 10:41 pm

I had another problem with Mapguide Enterprise 2009 recently pertaining to objects not being selectable.  Unlike my previous post on errors caused by layers, no errors were logged to the Mapguide server logs.  This problem is very likely specific to the enterprise version, as I was using the Autodesk FDO Provider for Oracle.

So a data connection was created pointing to the Oracle 10g schema.  This database contained a number of tables containing Lat/Long point geometry entities.  I created a layer pointing to the table in question.  I created a layer pointing to that data connection.  At this point the entities showed up as expected in the both the DWF and the AJAX viewers.  Once again, I could not select any of the entities.  I checked the server logs, no errors were reported.

In troubleshoot mode, I tried just about everything I could think of but nothing would work.  I simplified the theme, created new layers, removed all other layers from them map.  Eventually I created a new layer from another table.  Luckily, the entities on this layer could be selected.  It must be a problem with the underlying data.  On a hunch, I checked the table definitions – specifically looking at primary keys.  The selectable layer had a primary key defined, the problem layer did not.  (Good thing I cannot take credit for creating this source data =))

So, I created a primary key on the problem table, did a touch on the layer definition (opening the definition in Studio and saving it without any changes) and then left for twenty minutes.  I’m thinking there is some sort of caching going within the server, and I’m not sure how it works.  Immediately reloading the map after adding the primary key did not work – the entities were still not selectable.  When I came back – the items in the viewers were now selectable.

So long story short, if again you cannot select map entities using the Autodesk FDO Provider for Oracle ensure that the source table has a primary key defined.  Hopefully this saves someone some grief =)

Powered by WordPress

Switch to our mobile site