We have been doing extensive development using Silverlight, and have run into some barriers with the design of the application we are working on. Some of the issues we were able to mitigate with MVVM pattern. However, as the app has become more complex, dependencies have crept in between the viewmodels and the parent application.We are also running into trouble managing commands and events associated with the application - how do you have several components subscribe to the same event set without having to connect viewmodels together?

The application's Xap file has also grown to be fairly large, and it will be necessary to split the application up into separate chunks that are loaded only when required. Our current structure will not allow this.

Upon doing research into how to address these issues, I discovered the Prism framework from the Microsoft Patterns and Practices group. This appeared to be a great way to address a number of the issues.

Prism is a framework for composing applications from separate modules. It contains an approach for injecting components into others using the Unity framework (also a patterns and practices framework) to eliminate dependencies. It also has a very nice looking commanding approach implemented through an event aggregator publish/subscribe mechanism.

However, during reading through commentary on Prism, I also found the Managed Extendability Framework, from a different part of Microsoft which looked initially like it was a competing approach to solve similar issues.

Microsoft often does things like this (take the whole Linq/ Linq-SQL/Ado.net entity framework/Windows Communication foundation maze as an example...) in which they come out with several almost the same but not completely technology bits that overlap. Inevitably one of the approaches will be adopted at the expense of the other, which forces developers who adopted the wrong one to refactor to the winner.

 (More)

WCF is a great technology, but it is difficult to configure, and often the error messages are cryptic - if in fact you can get it to return exceptions at all.

Fiddler is a great way to debug WCF based services, but even that sometimes doesn't work if you are using the visual studio/cassini based web host.

Fortunately, adding the following code into your web.config file will put any exception information into a log file:

<system.diagnostics>

<sources>

<source name="System.ServiceModel"

switchValue="Information, ActivityTracing"

propagateActivity="true">

<listeners>

<add name="traceListener"

type="System.Diagnostics.XmlWriterTraceListener"

initializeData= "c:tempwcfErrors.svclog" />

</listeners>

</source>

</sources>

</system.diagnostics>

 (More)

We are now finally underway building the first version of what will become the Menome system.

One of the things we needed was a way of clustering points on a map. The idea is to reduce the number of points as the user zooms out by combining points together to keep performance up and to reduce map clutter.

The algorithm operates by creating a 'screen grid' and passing this to the server. As the user zooms and moves around the map, the boundary window they are looking at in lat/long, the height and width of the current window in pixels and the zoom level are passed to the server.

The first level of filtering happens on the SQL server by doing an intersection of the boundary window with the point geography stored in the SQL server.

Points inside the boundary are returned to the web server, where above a given zoom threshold (10 for now), they are passed through the clustering class. The clustering class works by creating a grid out of the current window. Two nested loops are created, which loop through the grid cells. Each points coordinates converted from lat/long to pixel, and checked against the current grid cell. Points found in the same grid cell are grouped together into a single point, and stored into the grid cell list indexed by the X and Y cell index multiplied together.

Fortunately, Johannes Kebeck has posted an algorithm for doing this on his fantastic blog The algorithm he presents is setup to return javascript, and is written in VB, so we changed it slightly to return a SiteLocationPoint object and to operate in C#, since that is the language we are using for the application we are building.

We have turned this into a class, which takes a list of points, and returns a list of clustered points. The main change we had to make to the algorithm itself was modifying the it to use a Dictionary to store the clustered points in the gridCells object instead of a jagged array, which cannot be declared dynamically in C#.

We used a dictionary with the X*Y grid cell as a key for storing/extracting points in a given grid cell. The other modification we need to make, which I will post once we figure it out, is a way of changing the clustering density.

Click more to get the source code.

 (More)

I recently completed an assessment and subsequent construction and deployment of a development management system for our software development team at Matrix

While Microsoft has brought out Team system for doing source control, automated build/test, its a fairly expensive product. It has the advantage of being an 'install and go' kind of thing, but the cost of it makes it prohibitive for smaller development teams.

There are also lots of great open source tools out there for performing these tasks that work very well. At Matrix where I work, I have assembled a set of tools that are doing a great job of letting us manage a very extensive set of code across a diverse team of people in a quick, easy and efficient manner. This blog post will review the tools we are using for this, and give examples of how to set it up.

 (More)

Configuring Silverlight to access a NT Authenticated WCF Services :
  • add .xap -> application/x-silverlight-app to the mime type in IIS to get IIS to recognize and transmit the mime type
  • add .xaml -> application/xaml+xml to the mime types in IIS to get IIS to recognize and transmit the mime type
  • add the clientaccesspolicy.xml to the root folder in IIS to get the cross domain working for wcf debugging
  • Ensure that you have the IIS virtual directory security set to use NT authentication only
If we modify or create new services inside the service class, it is necessary to make sure the URL is set correctly in the ServiceReferences.ClientConfig file in the Silverlight project when you update the service reference. It defaults to a value that is different than the value visual studio uses when the debugger is run, which causes an exception to be thrown when the silverlight call goes through to the service.

 (More)

While I am critical of Microsoft, its because I know they can do better than they have in recent years. If you put the dismal performance of Vista and the horrible marketing campaigns of late, Microsoft outside the consumer and platform sphere has created some incredibly innovative products for developers over the last few years. Linq, and WCF are just two recent examples - not to mention the new SQL server 2008 which is amazing as well - more on that in a later post...

Unfortunately, it is Microsoft business model that needs innovation - not their tools. It is mired in the world of PC software - often to the detriment of new and innovative ideas.

Fortunately, Silverlight looks like a breakthrough technology for Microsoft: mainly because it shows a change of attitude. Microsoft is finally getting serious about cross platform support, and the web as the application platform. I have often wondered why Microsoft has not made a .net VM host for other platforms - Mono aside. The obvious answer being fear of cannibalizing its windows franchise. I personally think Microsoft, if it were serious about this battle for the web, would make windows free for consumers, and instead shift its focus to a subscription service based model: say $50 a year for support for Windows or something to that effect. It would cost it a fortune initially, and would affect their stock price (could it get worse??) but would force the company to formally acknowledge what has already happened: Operating systems are a commodity.

Anyway - fantasy aside - It seems that Silverlight is at least a start at Microsoft opening its platform up to other operating systems.

Silverlight allows for .net managed code to run on any platform using Windows Presentation Framework. I am very excited about this, as many of the apps we are looking at building can then be made to run on any platform. It is of course possible to do this with Ajax, which I have done, but it will be nice to have the advantage of a full fledged debugger and a nice set of tools that finally is graphic designer friendly on the Microsoft side (Google of course has had this for a while with its GWT - I have never liked Microsoft's native implementation of asp.net Ajax - its complicated and messy).

I already have a version of a managed code graph written in C# using the open source Visifire control working in IE, Firefox, and Firefox on the mac (have to try linux next)... using the same code base. This graph gets its data from a WCF service that pulls data from our accounting system.

Here it is running in firefox on my MacBookPro:

d

Getting this working though was a bit difficult from a configuraion standpoint.

 (More)

Very exciting - we have setup SQL 2008 and I am now working on extending our syncrhonization system to incorporate spatial information....I will be making notes here as I work on figuring out the SQL spatial extensions. Some of these will be fairly simple to begin with, until I become familiar with the syntax.

To that end: one of our tables had lat/long information in it in standard floating point format. I needed a query to update this information into the new Geography column I created. The update query to do this:

update WaterWells set Coordinates =
geography::STPointFromText('POINT(' + CAST(LONGITUDE as varchar(50)) + ' ' + cast(LATTITUDE as varchar(50)) +')', 4326);


As noted in another post, I am using Dynamic Linq to build a generic query tool for a service layer I am constructing. In the process of doing so, I have run into the following error when I try to pass a query in for a Guid:

Operator '=' incompatible with operand types 'Guid' and 'String'


Very exciting news - an article co-authored by Barry Lawrence of BSTGlobal and myself based on a system now in production at Matrix has just been published in the Microsoft Architecture Journal.

The article is on the subject of Enterprise Identity Synchronization and describes a synchronization pattern and associate system architecture for keeping enterprise identity data up to date between disparate systems. In effect - it is a system for replicating identity memes around an organization.

This has proven to be a fascinating project from a number of standpoints, and I have learned a great deal from the experience of being involved in designing and building a services oriented workflow architecture. The implementation of the system has also been very fascinating, and is a real case study in how systems, people and processes are inherently intertwined. I will write a number of blog posts on the outcome of this project over the next few weeks.


As part of the workflow service project, I need to build an XML querying framework.

For this to work on the back end, I would like to use Linq - but in order to do so, I need to have it be capable of handling dynamically generated queries derived from the query XML coming into the service.

It appears that Microsoft has produced samples of this - Dynamic Query.

There are a number of good examples around:

ScottGu's dynamic query example:

Linq Dynamic Query C# class

Blog post that includes a join example:

The issue though with Dynamic Linq is that you appear to trade the strong typing associated with standard Linq for the flexiblity of Dynamic query.

A query executed with Dynamic Linq returns as a type of 'DynamicClass1' etc. which cannot be cast to other types. This means that a generic mapping process of some kind would have to be used to get the data back into some kind of strongly typed form.

In the case of what I am working on, I don't need the strong typing. I am working on setting up a service entry point for generic querying of data associated with the service in question. The query language coming in will be constructed in XML, and defined using a typical XML query pattern.

These queries will be translated to dynamic linq, which is then executed and mapped back to XML from the generic dynamic class generated.

 (More)

Was setting up to link our accounting database which runs on 32 bit SQL 2000 to our spatial database, which runs on 64 bit SQL 2005 and kept getting a strange error when executing the distributed query:

After trying the microsoft knowledge base article, which did not work, I found John Hofman's blog.

His method did work...Kudos you rule, and thanks for saving me hours of frustration!

(hit more to see original post).

 (More)

Due to the issues with multithreading on .net 1.1, the Microsoft people have coded up a great addition to .net called the BackgroundWorker object. This gizmo allows you to quickly and easily setup multithreading for winforms apps. Seems to work very well, and is incredibly useful for building fast, responsive winforms UIs that communicate with data services.

The one trick though is when doing updates to UI components, you need to call the InvokeRequired to find out if the thread requires marshalling before accessing control in question.

This bit of code seems to do the trick:

//need to call InvokeRequired to check
//if thread need marshalling, to get the thread onto
//the same thread as the thread who owns the controls
if (this.InvokeRequired)
{
this.Invoke(new EventHandler(delegate
{
this.listBoxClients.Items.Add(listboxText.ToString());
}));
}
else
{
this.listBoxClients.Items.Add(listboxText.ToString());
}


One of the unfortunate side effects of deploying a fancy new accounting system that supports web service calls, is that people want to interface it with all sorts of things. One of the primary reporting interfaces therefore naturally becomes Excel.

Excel is a good tool for what it does, but for a programmer: it can be a nightmare to work in. Fortunately, the new VSTO 2005 is pretty good at turning the mess that is Excel into something possible to write good code in.

The key to this are Action Panes. These are useful: you can set up nice object oriented data interfaces/displays, and use them to pump data into excel's nasty world of ranges and cells.

The key is to make sure you completely separate your data bits from the spreadsheet bits. By this I mean put any data feeds into the action panes, and use named ranges and range object operations to 'push' the data into the spreadsheet. Don't use the Excel List Object unless you absolutely have to.

Users will typically build lot of logic built into spreadsheets, and you have virtually no control over what they do with the sheet once its in the 'wild'. Users will expect to be able to do all the normal things they would do with the spreadsheet and the specialized objects don't work exactly the same way as normal cells in the spreadsheet do. The Action Panes are nicely seperated, and the users can't modify them.

 (More)

Needed to build a multithreaded handler for getting data from multiple web service sources and combine the result together into a single graph.

Threading in winforms in .net 1.1 was tricky, since any forms object created on the primary thread will not like being accessed on a second thread (cross threading).

This is addressed in .net 2.0, by the BackgroundWorker object - and can be addressed in .net 1.1 by using various thread locking bits, but its a real pain to do.

Fortunately, Juval Lowy wrote up an excellent article on the subject of threading in both .net 2.0 and 1.1. The article includes examples of the issues of cross-threading, how to use the background worker in .net 2.0 and even goes so far as to write up a .net 1.1 equivalent object for use in .net 1.1. I used the object in a project I had to maintain in .net 1.1, and it works great.

Here are other Excellent articles related to .net multithreading:

http://www.devx.com/codemag/Article/20639?trk=DXRSS_DOTNET

http://weblogs.asp.net/rosherove/articles/BackgroundWorker.aspx

http://www.albahari.com/threading/part3.html#_BackgroundWorker


Needed to makeup a regex for matching Alberta Location Township Range formatted codes. It appears this will work:

[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9]W*


Using SSIS from M$ SQL 2005 to build a massive data import for an accounting system (yes very painful). SSIS itself looks very good - however, I have been running into a few strange things.

For no particular reason, my packages stopped opening with a somewhat cryptic error that indicated the packages had been 'corrupted':

"package might be corrupted ssis"

Resolution turned out to be to re-regsvr the XML dlls. Don't know how, why or what would cause them to become unregistered, or why it would affect SSIS outside of their being required to parse the XML that makes up the package... At any rate, if you experience that error, then run:

regsvr32 msxml3.dll
regsvr32 msxml4.dll
regsvr32 msxml6.dll

This should clear it up...

 (More)

I have been busy refactoring the network, server and information infastructure layers for the company I work for recently. Now that that unpleasantness is nearly complete, I can again return to the more pleasant world of creating software.

However, even that has its dark side - of which one ongoing point of pain is the Data Access Layer.

 (More)

From... Microsoft!

While the comments I am getting are already 'Would you want to depend on a Robot running windows??' The development kit looks pretty good - the nice thing is that the components are pretty cheap....

I am interested both in this from a hobbyist standpoint, and potentially for work - we do lots of remote sensing activities, and having a cheap, fast way of building field sensor gizmos would be very cool...

http://msdn.microsoft.com/robotics/

http://www.roboticsconnection.com/index.html

 (More)

Got my Sharepoint library event handler generic class working a few weeks ago.

Went through the process of setting up the Sharepoint Portal system on the server, and in the process did an upgrade on the system. Fortunately its not fully deployed yet, since as it turned out the installation of STS service pack 2 makes some changes to the security plumbing in sharepoint.

The impersonation technique I was using no longer is supported under SP2 - so I was suddenly getting strange intermitted 'Impersonation Failure' errors cropping up.

Some research into this revealed the following:

Document library event handlers that use object model code without explicit impersonation fail with the "Cannot complete this action" error message after Windows SharePoint Services Service Pack 2 is installed

here


I have been working on building a Google Earth search engine interface. I have successfully got it to the point where I can get two way communication going.

The idea is to have a page inside the Google Earth browser that displays search criteria for a database of items that have spatial locations displayed in the Google Earth client.

Executing a search will display the Placemarks of the items that match the search criteria.

I will be posting a set of articles on this subject coming up, and posting the source code for all of it to SourceForge. This will include a .net KML class library, as well as a sample Google Earth based data search web page.


 (More)

I have been hearing a lot about this both from Microsoft and from developers/companies I know in town.

Its a Don Box creation, and looks absolutely excellent. I was planning to build up a workflow engine of my own, as I require one for a number of things that I am working on, and have tried Biztalk a few times, only to find that its too complicated and fiddly for most workflow related tasks. I will have a look at the new version of Biztalk that is coming out shortly, but I think this Windows Workflow looks a great deal more applicable for most of the cases I am working on.

 (More)

The new Visual Studio has a nice code snippet manager tool that is capable of auto-decorating code for you. It is also customizeable, which is great.

I like my properties for example to look a certain way, decorated with #region markup so that I can collapse/expand them to keep things looking clean.

By modifying the XML in the snippet source for property markup, I was able to get an auto-generated property markup setup for myself - which is a huge timesaver.

 (More)

There have been some changes made to the way the Enterprise Library is setup for the .net 2.0 framework. I will document the differences and how to here as I figure things out.

The first is that they have dropped the configuration block, as the 2.0 framework has a System.Configuration namespace that handles the configuration management internally.

Here is a sample:

 (More)

How to setup the smartphone emulator to be able to access web services:

  1. Go to Settings, then Data Connections (Shortcut: L, 8, 9, 2).
  2. Change Work Connection to NetCard (Is that short for Network Card? Who knows? *shrug*).
  3. Click Done.
  4. Go into Internet Explorer (Shortcut: L, 4).
  5. Click Menu, then Options (Shortcut: R, 7).
  6. Uncheck Automatically detect settings.
  7. Change Select Network to Work.
  8. Click Done.

You can now browse around with IE and your WebService calls will now work as expected. Well, almost...remember that when adding your Web Reference for the name of the server, use the name of your local development machine, not "localhost". The emulator doesn't get that when you say localhost, you really mean your machine.

From HERE:


Thanks to Greg Pringle for this one:

.Net does not support serializing anything with an IDictionary interface. I have run into a number of places where I would like to serialize/deserialize collections with that interface. Greg tracked down a way of doing this using an undocumented interface..

Details are here:

http://msdn.microsoft.com/msdnmag/issues/03/06/XMLFiles/

Answer is under “Q: I've noticed that XmlSerializer won't serialize objects that implement IDictionary by default. Is there any way around this?”

Update: Found an addtional possible alternative: Xtream serializer object found HERE


Have to give this one a try:

http://msdn.microsoft.com/coding4fun/diy/controllights/default.aspx

Haha - could build a remote pet feeder..

http://www.smarthome.com/6104.html

Wonder if this would work for babysitting? Save lots of $ on that...could wire it up to my smartphone! (just kidding)


Found this while looking for some info on the crypto enterprise library block: http://www.pnplive.com/

The patterns team does great stuff - use it all the time. Unfortunately I just heard Ward Cunnignham is leaving Microsoft and the patterns team to join the Eclipse project. I had the honour of having a beer with Ward at last years OOPSLA confrence in Vancouver...

 (More)

Date calculations in infopath taken from: http://blogs.msdn.com/infopath/

(stored it here for searchability)

 (More)

There have been several occasions when I have needed to move an infopath form and/or web services its using.

Not a very easy thing to do: the URLs get all bound into the template, and are very tough to fix. This is a real nuisance - especially if you are doing dev/test on different servers.

Microsoft has just released a tool to deal with this though and its located here


Was looking around the google code competition. Interesting - but primarily algorithm centric contest.

I would need to do some serious study to get my algorithms back up to par again before getting involved something like that. Even so - algorithms are something that is on my list of continuous improvement study items. From that contest link, I found the Top Coders site, which has a great set of tutorials and resources on algorithms:

http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=alg_index

 (More)
Sure the new SQL server and .net versions are a big deal: but bigger ones to me are the increasing focus/shift to XML. Finally - microsoft office documents will be stored in XML with office 12. This is huge. The move essentially turns  (More)

Got a few things on the go that require the generation and read-back of SQL databases from class libraries and/or datasets.

Here are resources that I have found that pertain to this subject:

 (More)

Been looking for a pop3 email component so that I can read email back from a server and process it. SA used to have a good one, but they have pulled it off their site. I don't feel like writing a component like that at present, unless I really really have to, as it would be time consuming to do, and while its of value, its something that should be out there already.

 (More)

At some point I will be getting into multiple configuration deployments for the code... So: in order to do that, it is convienient to have multiple configs for different environments.

This blog has a post and a plug-in for doing this...


Investigating this forms processing engine I am working on has lead me to software factories. I have been reading the Software Factories book - its good.

Here are some additional resources I have found while investigating this.

 (More)

Regex for matching something in brackets but exclude brackets: (word)

(?<=()(.*)(?=))

Regex for getting time:
bd{2}:d{2}:d{2}

Regex for getting two letter words:
(?<=(?:s|G|A))w{2}(?=(?:s|Z|.|?|!))

Regex for seperating a number from leading zeros and a dash:
[123456789](d+)(?=-.+)

Some good regex tools:
http://www.codeproject.com/dotnet/RegexTutorial.asp

and the REgex coach is quite good as well.


Been battling a really tough exception - it manifests as a nullReferenceException - but not always with the same stack trace. Thanks to Jeff Attwoods exception code though, I have been able to build up a good base of data to go from for diagnosing the issue.


The latest information points back to disposal of forms again. Acccording to some information I found, the first place to look is the ShowDialog related forms - which as it turns out, must be manually disposed of...

 (More)

To post the source of the great exception handler: its from Jeff Atwood on the CodeProject : he runs a website called the Coding Horror after Steve McConnels Code Complete...

Source is here:

http://www.codeproject.com/dotnet/ExceptionHandling.asp

His blog (GREAT reference) is here:

http://www.codinghorror.com/blog/

 (More)

I deployed the new version of the application I am working on to the user audience last night. The enterprise application updater block is working extremely well. There was only 1 machine that it did not work on, and that was due to the user not having applied updates in the last 3 years to the box...So the bits downloader was not present on the system in question.

I also have added an email exception handler that takes a screen capture and emails the exceptions to me with all the stack trace etc. It is done using some exception handler code I found I think on the code project (I likely listed it earlier in the blog here as its very very good and quite useful).

So now with the smartphone and with the exception manager, I can find out and nail down very quickly where, and what are causing errors with the system. I was finding that on only a few machines I was getting some strange exceptions. These seemed to be UI related, but not very specific.

AFter some digging I have found it may be due to a bug in .net 1.1.....


 (More)

Been doing some work with reporting services. I should post some of the code here shortly when I get it finished up.

Reporting services is proving to be a great tool for doing all sorts of things. I remember how difficult it was to build reports - no longer. Anyone with any basic form of skill can set this thing up and get it workign in no time.

 (More)

After some thought, I have pursued MS OLAP cubes via analysis services coupled with reporting services as a way to plow through the mass of accunting data that exists in this accounting database.

 (More)

Article on best practices for team development with Biztalk. I have found lots of articles on how to set biztalk up, but just this one thus far on getting a team environment setup for developing...

 (More)

Two good articles on how to impliment splash screens and detect user inactivity:

http://www.codeproject.com/csharp/uim.asp

http://www.developersdex.com/gurus/code/97.asp

 (More)

I needed to launch the bug tracking app from my smart client application.

The following two lines of code are all you need:

using System.Diagnostics;
private
void LaunchBrowser(string url)
{
ProcessStartInfo psi =
new ProcessStartInfo(url);
_browserProcess = Process.Start(psi);
}

 (More)

I am just working on setting up my in the latest m$ marketing speak, Smart Client application with the Enterprise Library updater block.

I am going to see if I can get it working off a linux server just for fun as well.

Method to be posted here as I figure it out.

 (More)

As my current project is becoming more complex, I am now investigating Nant to automate builds of the project.

I would like to have it do a daily build, run unit tests, then put the build (if successful etc) into the correct locations with version # etc.

 (More)

As my current project is becoming more complex, I am now investigating Nant to automate builds of the project.

I would like to have it do a daily build, run unit tests, then put the build (if successful etc) into the correct locations with version # etc.

 (More)

I have been building a fairly sophisticated business metrics and time managment system for my employer recently.

To bring the tool to the next level, I am making use of a number of third party components. There are some excellent resources out there for this sort of develompent, both commercial and open source.

 (More)

Good example of a singleton pattern in C#

http://codeguru.earthweb.com/columns/DotNet/article.php/c7617/

I have a registry singleton source code pattern I will add up here once I get a few minutess

 (More)
An application I am building at present has some interesting performance requirements and constraints. The database was built by another consultant, and is not well designed. The users need the data presented in a very different manner than the database allows for - so Design Patterns to the rescue! By using a datamapper, domain, observer, registry and unit of work I was able to get the application working. However things took a turn for the worse when I discovered the app was leaking memory (More)

Been working on trying to get sorted collections figured out in C#. My first cut at it was a bit gnarly - (the post is on here), but in my latest quest, I found this article on sorting custom collections by J Ambrose Little.

 (More)

This is rather interesting - I noticed it in a chunk of code I was looking at while searching for something else - but its a technquie for mapping objects to relational tables. It only works in the case where the field names in the table are the same as the object properties, but it likely could be modified to provide more dynamic mapping through an XML list or something to that effect.

 (More)

This looks quite interesting - an embedded .net environment for sensor applications:

http://www.dotnetcpu.com/products.aspx?3

Its very inexpensive compared to the smart motes that run TinyOS as well - those are in the thousands of dollars for a kit, this one is 500 bucks.

More details here: http://www.windowsfordevices.com/news/NS4666205829.html

Now I know what I want for xmas ;-)


Apparently there is a better way to handle web service calls from Sharepoint than I have been using.

http://msdn.microsoft.com/library/en-us/odc_SP2003_ta/html/sharepoint_integrating_sps_and_infopath.asp?frame=true

I could not get a virtual directory under sharepoint working for hosting a web service - it looks like there is a technique for doing this, by supressing the processing of the directory by sharepoint (which makes sense). In addition, there are methods for eliminating the annoying activeX messages that pop up when calling in from an unsigned form.

 (More)

Two new ones:

 Xtreme simplicity Refactory: http://www.xtreme-simplicity.net/

Jet Brain's resharper - http://www.jetbrains.com/resharper/

haven't tried them out yet, but certainly worth investigating!


I ran into a similar situation where I needed a hastable sorted on different values, and could not easily use a database to do the sort.
 
Eric Gunnerson as it turns out had published an article on MSDN for improving foreach - he wanted to have a similar facility as found in perl for sorting using foreach...
 
Something else that's common when dealing with data in a hashtable is wanting to order the entries based on the values in the hashtable. We'd like to be able to use the same IComparable approach as we used previously, but that takes a little more work. What we need is a class that has an IComparable implementation that looks up the hashtable values from the keys, and then compares those values.
This is done by creating another class named SortHashValueItem. An instance of this class is created for each key in the hashtable, storing the hashtable key, the hashtable reference, and an IComparer object (if applicable). This class implements IComparable, and the CompareTo() function forwards the comparison to the values in the hashtable or the IComparer.

 
 
So - I have used his code, and the code from CodeSmith to make a hashtable that has a sort method on it. Its probably terribly inefficient (time constraints, refactor when I have the opportunity) but it works.
 
Caveats aside - on the hashtable, which stores a collection of Participants for an event, I have created a set of sort methods for each value I want to sort on. I use Erics method of sorting using foreach, and a custom comparer to sort the hashtable into an arraylist, which is then returned.
 
First, I populate the collection, then generate a sorted version of it sorting on whatever parameter required by calling the appropriate method. This returns an arraylist of the contents of the hashtable sorted on in this case the last name. The arraylist can then be bound to a control etc.

ParticipantCollection registeredParticipants = ParticipantCollection.Find(m_currentOrgID, myEvent,

true);
ArrayList sortedParticipants = registeredParticipants.SortLastName();
 
Sort method on ParticipantCollection - uses an Eric Gunnerson IterSortHashValue class, typed to the class I am using:
#region
Sort Methods
#region
(Method) SortLastName/// <summary>
/// Sorts the contents of the collection based on the last name
/// A better way of implimenting this is required.
/// </summary>
/// <returns>Returns an arraylist of participants from the collection sorted by last name</returns>
{
ArrayList sortedItems =
{
sortedItems.Add(
}
}
public ArrayList SortLastName()new ArrayList();foreach (int participantID in new ParticipantCollectionSort(this, new ParticipantComparer()))this[participantID]); return sortedItems;
#endregion
ParticipantComparer class:
#region
(Class) ParticipantComparer/// <summary>
/// ParticipantComparer - defines allowable comparisions to be made between participant objects.
/// This class is used to assist in sorting by defining what property to use to do the sort
/// </summary>
{
public class ParticipantComparer: IComparer /// <summary>
/// Compare Participant objects based on the LastName property. The implimentation IComparer requires
/// type Object to be passed in. The method internally defines that Participant objects are the only
/// type allowable
/// </summary>
/// <param name="x">Participant Object</param>
/// <param name="y">Participant Object</param>
/// <returns></returns>
{
{
("The objects to compare must be of type 'Participant'");
}
}
}
public int Compare(object x, object y) if (!(x is Participant && y is Participant)) throw new ArgumentExceptionstring tempObj1 = ((Participant)x).LastName;string tempObj2 = ((Participant)y).LastName;return tempObj1.ToString().CompareTo (tempObj2.ToString ());
#endregion
 ParticipantCollectionSort - from Eric Gunnerson's Iter collection code (typed again)
using
System;
using
System.Collections;
namespace
{
DomainModel/// <summary>
/// Iterate the keys in a hashtable, ordering them by the values
/// corresponding to those keys. Either uses the defined ordering on the
/// values or a passed-in IComparer implementation
/// </summary>
{
{
ArrayList items =
{
public class ParticipantCollectionSort: IEnumerableinternal class IterSortHashValueEnumerator: IEnumeratornew ArrayList();int currentItem;internal IterSortHashValueEnumerator(ParticipantCollection hashtable, IComparer comparer)// create a new SortHashValueItem for each key.
{
SortHashValueItem item =
items.Add(item);
}
currentItem = -1;
items.Sort();
}
{
currentItem = -1;
}
{
currentItem++;
}
{
foreach (int key in hashtable.Keys)new SortHashValueItem(hashtable, key, comparer);public void Reset()public bool MoveNext()if (currentItem == items.Count)return false;return true;public object Currentget
{
SortHashValueItem current = (SortHashValueItem) items[currentItem];
}
}
}
return current.Key;// item to hold a key and the related hash table
{
ParticipantCollection hashtable;
IComparer comparer;
{
}
{
internal class SortHashValueItem: IComparableint key;public SortHashValueItem(ParticipantCollection hashtable, int key, IComparer comparer)this.hashtable = hashtable;this.key = key;this.comparer = comparer;public object Keyget
{
}
}
{
SortHashValueItem item2 = (SortHashValueItem) object2;
return key;public int CompareTo(object object2)// get the two values for these keys...
{
}
object value1 = hashtable[key];object value2 = item2.hashtable[item2.key];if (comparer != null)return comparer.Compare(value1 ,value2);else
{
// compare one to another. They must implement IComparable...
IComparable comparable = (IComparable) value1;
}
}
}
return comparable.CompareTo(value2);/// <summary>
/// Create an instance of the IterSortHashValue class
/// </summary>
/// <param name="hashtable">The hashtable to use</param>
{
}
public ParticipantCollectionSort(ParticipantCollection hashtable)this.hashtable = hashtable;/// <summary>
/// Create an instance of the IterSortHashValue class, using a
/// specific comparer
/// </summary>
/// <param name="hashtable">The hashtable to use</param>
/// <param name="comparer">The comparer to use</param>
{
}
{
}
ParticipantCollection hashtable;
IComparer comparer;
}
}
public ParticipantCollectionSort(ParticipantCollection hashtable, IComparer comparer)this.hashtable = hashtable;this.comparer = comparer;public IEnumerator GetEnumerator()return new IterSortHashValueEnumerator(hashtable, comparer);
 (More)

Very cool C# extensions that allow for sorting hashtables, reversing etc..

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncscol/html/csharp01212002.asp


This looks very interesting - Mono itself naturally, but also this iFolder system from Novell. Sounds like something I have been wanting to try to build for a while now. Time time..Its always a problem. Sooner or later someone finds it...

http://forge.novell.com/modules/xfmod/project/?ifolder

http://arstechnica.com/news/posts/20040714-3994.html


C# does not have a native IsNumeric test. There are 3 main ways of doing this:

Try/Catch on Convert.ToDouble (BAD - slow, inelegant)

Regex - effective, fast, but cases are harder to establish to cover all situations

Incremental Char - loops through each character in the string, and uses System.Char.IsNumber to test. This according to benchmarking is the fastest, and also likely the safest. (http://aspalliance.com/articleViewer.aspx?aId=80&pId=2)

Code is below:

///


  /// Gets whether or not the expression is numeric
  /// by checking each character to see if it is a number.
  ///

  /// Value to check.
  /// Whether or not the expression is numeric
  /// by checking each character to see if it is a number.

  public bool IncrementalChar(string expression)
  {
   bool hasDecimal = false;
   for(int i=0;i   {
    // Check for decimal
    if (expression[i] == '.')
    {
     if (hasDecimal) // 2nd decimal
      return false;
     else // 1st decimal
     {
      // inform loop decimal found and continue
      hasDecimal = true;
      continue;
     }
    }
    // check if number
    if(!char.IsNumber(expression[i]))
     return false;
   }
   return true;
  }


http://msdn.microsoft.com/office/default.aspx?pull=/library/en-us/odc_ip2003_ta/html/ODC_INFDigitallySigningData1.asp

See this in the MSDN LibrarySee This in MSDN Library

Page Options

Digitally Signing Data in InfoPath 2003

Mihaela Cris
Mark Roberts
Microsoft Corporation

August 2004

Applies to:
    Microsoft Office InfoPath 2003
    Microsoft Office InfoPath 2003 Toolkit for Visual Studio .NET

Summary: Microsoft Office InfoPath 2003 Service Pack (SP) 1 provides new digital signatures features, as well as additions to the InfoPath object model for working with digital signatures programmatically. For example, you can specify sets of data in the form that can be signed separately. For each set of data that can be signed, you can specify whether to allow a single signature or multiple signatures, and the relationship among signatures. With these capabilities, you can customize the digital signatures feature so you can track the status of valuable data. (42 printed pages)

Contents

Introduction
Valid Digital Certificates for Signing Data in InfoPath Forms
Defining Counter-Signatures and Co-Signatures
Designing InfoPath Forms with Digital Signatures
Understanding the Digital Signature Status and Verification Process
The Verify Digital Signature Dialog Box and Nonrepudiation Data
Using the InfoPath Object Model to Work with Forms Configured for Signing Data
Code Samples
Conclusion

Introduction

Many business and organizational scenarios require the ability to protect and track valuable data exchanged through documents. Information about who creates the document, and how, when, and by whom certain data is approved is invaluable to readers and contributors to the document. This information reveals how the document was modified during its lifetime, and provides those who worked on the document with a method for certifying their contributions. Microsoft Office InfoPath 2003 SP 1 provides a way to add and track this kind of information by using digital signatures in documents and data created and managed with InfoPath forms.

Digital signatures provide a standards-based method for helping to secure and certify all or specific parts of a document. By using digital certificates, encryption technologies, and other elements of the public key infrastructure, digital signatures provide a way to detect whether sensitive information has been tampered with and to confirm that the data originating from the signer has not been altered since it was signed. For information on how digital signature technology is implemented in the Microsoft Windows platform, see Digital Signatures. For information on digital certificates, see Digital Certificates.

You can use digital signatures in InfoPath 2003 SP 1 to:

  • Digitally sign the form template (.xsn) file to help ensure the integrity and authenticity of the form template.
  • Digitally sign data when filling out XML forms, to help ensure the integrity and authenticity of the data, and to provide support for the nonrepudiation of the signatures and the signed data.

This article focuses on the second application of digital signatures: designing form templates that allow users to digitally sign the data in an entire form or parts of the form as they fill them out. For more information, see Digitally sign a form template.

The digital signatures infrastructure for signing data in InfoPath forms follows the Worldwide Web Consortium (W3C) XML-Signature Syntax and Processing recommendation (XML Signatures). The infrastructure is based on support from Microsoft XML Core Services (MSXML) 5.0 for Microsoft Office. XML Signatures is designed for transactions that involve XML documents and data. A powerful feature of XML Signatures is the ability to sign only specific sets of data within an XML document. For more information, see W3C XML-Signature Syntax and Processing. For more information on how XML Signatures are implemented in MSXML 5.0, see XML Digital Signatures.

The digital signatures InfoPath creates also provide interoperability with the classes that Microsoft .NET Framework 1.1 provides for working with digital signatures. Applications that use the .NET Framework signature verification classes can verify the signatures that InfoPath creates. Similarly, the InfoPath digital signatures infrastructure can successfully verify digital signatures created by applications that use the .NET Framework digital signatures classes when the signatures are applied to data hosted in InfoPath forms. For more information and code samples, see Verify and Add Digital Signatures to Form Data in InfoPath 2003 Using MSXML 5.0 or .NET Framework Managed Code.

In addition to the user interface commands and features for designing and editing forms that enable digital signing of data, InfoPath provides programmability support for digital signatures. For example, InfoPath allows access to the sets of signable data defined in the form, to the signatures associated with each set of signed data, and to the digital certificates used to create the signatures. You can customize the OnSign event handler in fully trusted forms, thus providing support for advanced processing of digital signatures in InfoPath forms.

This article provides conceptual, procedural, and programming information on the following InfoPath data signing features:

  • The kinds of digital certificates that are valid for signing data in InfoPath forms.
  • The difference between co-signing and counter-signing data.
  • How to design and configure forms to enable digital signatures, and how users of InfoPath forms work with digital signatures.
  • An overview of the object model for extending and working with digital signatures in InfoPath form code, and examples of how to customize the OnSign event handler for forms you configure for signing data.
Note   The digital signatures features described in this article require InfoPath 2003 with Microsoft Office 2003 Service Pack 1 or later. For information on downloading Office 2003 updates, see the Office Online Downloads page.

Valid Digital Certificates for Signing Data in InfoPath Forms

Not all digital certificates can be used to sign data in InfoPath forms. For a certificate to be valid, it must be an X.509 digital certificate with the following set of characteristics:

  • The Key Usage attribute value must include Digital Signature or Non-Repudiation. While certificates with the value set to Digital Signature or Both can be used to sign, certificates with the value set to Exchange cannot be used to sign data in InfoPath forms.
  • The certificate must not be expired or revoked, and the date of issue must be in the past.
  • The certificate must be associated with a private key on the user's computer.
  • To be trusted, the certificate authority that issued the certificate must be in the Trusted Root Certification Authorities store on the user's computer.
    Note   Installed digital certificates that are not trusted are available, and can be used to sign data in InfoPath forms, even though they create a signature that is not trusted. However, the signature becomes valid once the certificate authority that issued the certificate is added to the Trusted Root Certification Authorities store on a user's computer.

Viewing and Managing Digital Certificates

You can view and manage the digital certificates stored on a computer.

To view and manage digital certificates

  1. In Microsoft Windows XP or Microsoft Windows 2000, on the Start menu, click Run.
  2. In the Open box, type MMC, and then click OK.
  3. On the File menu, click Add/Remove Snap-in.
  4. In the Add/Remove Snap-in dialog box, click Add.
  5. In the Add Standalone Snap-in dialog box, click Certificates, and then click Add.
  6. In the Certificates snap-in dialog box, click My user account, and then click Finish.
  7. In the Add Standalone Snap-in dialog box, click Close.
  8. In the Add/Remove Snap-in dialog box, click OK.

Certificates that InfoPath can use for signing data become a subset of the certificates installed in the Personal folder. The certificates of trusted certification authorities are installed in the Trusted Root Certification Authorities folder.

Requesting a Digital Certificate from the Certificates Snap-in

You can request a digital certificate if your company or organizational intranet is configured to provide digital certificates from the Certificates Snap-in.

To request a digital certificate from the Certificates Snap-in

  1. Open the Certificates Snap-in (see Viewing and Managing Digital Certificates).
  2. Right-click the Personal folder, point to All Tasks, and then click Request New Certificate.

Requesting a Digital Certificate from a Windows Server 2003 Certificate Authority

You can request a digital certificate if your company or organizational intranet is configured to provide digital certificates from a Microsoft Windows Server 2003 Certificate Authority.

To request a digital certificate from a Microsoft Windows Server 2003 Certificate Authority

  1. Open the Microsoft Certificate Services Web page (request this information from your system administrator).
  2. Click the Request a certificate link, and then click the advanced certificate request link.
  3. Click the Create and submit a request to this CA link.
  4. On the Advanced Certificate Request page, fill in the requested information, making sure to specify the Key Usage value as Signature or Both.
  5. Click Submit, and then click Install this certificate. If the certificate for the issuing certificate authority (CA) is not already in your Trusted Root Certification Authorities folder, you are prompted to add the CA to this folder. Click Yes.

You can also obtain a digital certificate from a certification authority such as VeriSign, Inc., Entrust, or GlobalSign, or from your system administrator.

Defining Counter-Signatures and Co-Signatures

When you set up specific parts of data for signing in a form that you create with InfoPath 2003 SP 1, you can choose to configure the digital signatures as either co-signatures or counter-signatures. Additionally, you can restrict the number of signatures to allow only one. When you configure digital signatures for the entire form, by default, optional counter-signatures can follow the initial signature. It is possible to allow only one signature when you configure a form for signing the entire form, but this requires writing custom code in the OnSign event hander.

Co-signing is the action of allowing two or more parallel and independent signatures on the same set of data. The status of any co-signature does not affect the status of other co-signatures or prevent the addition of other signatures to the same set of data. Along with each signature, InfoPath stores some additional data, such as comments and non-repudiation data, in the Signature element of the document. If the signed data in the form is tampered with, all co-signatures associated with that set of data become invalid. If the data in the Signature element, such as the nonrepudiation data or the comments associated with it, is tampered with, then only that signature becomes invalid. When using co-signatures for a specific set of signed data, any signature in the list of co-signatures can be deleted at any time without affecting the other signatures. Additionally, InfoPath allows adding new co-signatures, even if the status of a previously added signature is other than Valid.

Counter-signing is the action of signing data that includes another signature. Counter-signing requires that signatures have a precise sequence in which they can be deleted without invalidating the other signatures. Adding the first signature to a set of data signs the data itself. Adding a second signature does not sign the data in the form, but instead signs the first signature. Each additional counter-signature signs the previous signature. If the signed data itself is tampered with, only the first signature in the list becomes invalid; the status of the rest of the counter-signatures remains unchanged. If the data stored with a particular signature (in the Signature element) is tampered with, such as the comments or nonrepudiation information for that signature, then that signature and the following signature become invalid. For a specific set of signable data, only the last signature in the list can be deleted without affecting any of the others. For a set of signable data configured for counter-signatures, no other signatures can be added after a signature with the status other than Valid. That signature must be deleted before additional counter-signatures can be added.

Table 1 summarizes the functionality associated with co-signatures and counter-signatures in InfoPath 2003 SP 1.

Table 1. Types of Signatures and their Relationships in InfoPath 2003 SP 1

Signature relationshipCo-signaturesCounter-signaturesAllow only one signature
Signing the entire formNoYesNot from the user interface, but you can limit to one signature by customizing the OnSign event.
Signing a part of the formYesYesYes
Can have additional signatures when the status of a signature in the list is InvalidYes
(after a warning)
NoNo
Can have additional signatures when the status of a signature in the list is ErrorYes
(after a warning)
NoNo
Can have additional signatures when the status of a signature in the list is RevokedYes
(after a warning)
NoNo
Can have additional signatures when the status of a signature in the list is Not TrustedYesYes
(after a warning)
No
Can have additional signatures when the status of a signature in the list is ExpiredYesYes
(after a warning)
No

Designing InfoPath Forms with Digital Signatures

InfoPath 2003 SP 1 allows users either to sign all of the data in a form when they edit it, or to sign parts of the data in the form. You can implement these features when you design your InfoPath form templates, and you can customize the XPath expression with which you specify a set of signable data.

Enabling Digital Signatures for the Entire Form

When you enable digital signatures for an entire form, the form users must enter all the data they require before they sign the form. After the first signature is added, all controls in the form and the form's XML Document Object Model (DOM) become read-only, and the text [Signed] appears in the title bar. Other users who open the form cannot enter data; they can only add, remove, or verify counter-signatures.

Signing the form locks all the data in the form, including data that does not appear in any of the views. This data includes the form header, which specifies the path to the form template. Because the form template path is signed, changing the path to the form template specified in the signed XML form (for example, to correct the path after moving the form template) invalidates the first signature, while any counter-signatures remain valid. If your usage scenario involves moving the form template, you can avoid invalidating any signatures by including all of the form data in a single section and defining this section as a set of signable data that uses counter-signatures. This approach not only solves the template location problem but also supports the features specific to partial signatures. These features include the in-document display of digital signatures and the ability to specify which controls are disabled when the data is signed.

Configuring digital signatures for the entire form has the following consequences and features:

  • The form's header node is included in the data.
  • Only counter-signatures are supported.
  • You can define an optional prompt that appears if the user does not sign the form before submitting it.
  • InfoPath stores all signatures in a signatures container node, which is a child of the root node.

To limit users to only one signature when signing the entire form, you can customize the OnSign event. For more information and sample code, see Limiting the Number of Signatures in a SignedDataBlock Object.

To enable digital signatures for the entire form

  1. On the Tools menu, click Form Options.
  2. On the Digital Signatures tab, select Enable digital signatures for the entire form (Figure 1).
  3. Optionally, you can select the Prompt user to sign a form if it is submitted without a signature check box, and then enable Submit commands and other settings. Note that this option only provides a prompt; it does not actually prevent submitting, if the user chooses not to sign the form.

Figure 1. Enabling digital signatures for the entire form, including a prompt to sign the form if it is submitted without a signature 

Enabling Digital Signatures for Parts of the Form

When you enable digital signatures for parts of the form, the signatures apply only to specific data in the form. To enable digital signing for specific data in the form, you must define a set of signable data. Each part of the form that requires signing must be associated with a set of signable data.

The InfoPath user interface provides two ways to enable digital signatures for parts of the form: by using the Form Options dialog box or by using the Section Properties dialog box (applies only to Section or Optional Section controls). You can use either method to specify signing for a set of data; the difference is in the way InfoPath displays the signatures in the form view and in the way the controls become disabled by default when signed.

You can enable digital signatures for specific data in the form for individual controls or for a group of controls. The control or group of controls can be in a container such as a section or optional section.

The following limitations apply to digital signatures enabled for parts of a form:

  • By default, the InfoPath digital signatures infrastructure does not support enabling digital signatures for an individual item in a repeating element; a user can only sign the entire element. For example, if you enable digital signatures for a section or control within a repeating section, adding a digital signature to one of the repeating items signs all items in the section.
  • The first time you switch settings from signing the entire form to signing specific data in the form (by using the Digital Signatures tab on the Form Options dialog box), InfoPath saves the change but does not display it in design mode. Although users can sign the form when they fill it out, the form appears in design mode as if signatures are not defined. To display the change in design mode, you must repeat the operation for configuring digital signatures for specific data in the form.

Enabling Signatures for Parts of the Form with the Form Options Dialog Box

You can use the Digital Signatures tab on the Forms Options dialog box to enable digital signatures for parts of the form and to create the specifications for sets of signable data (Figure 2).

Figure 2. Enabling digital signatures for parts of the form with the Form Options dialog box 

Note   With the Digital Signatures tab on the Form Options dialog box, you can add, remove, and modify sets of signable data. It is the only user interface element with which you can delete the definitions of sets of signable data and change the mode for digitally signing data to signing the entire form, to signing sets of data, or to no signing whatsoever. You can only use the Section Properties dialog box to change from signing the entire form to signing sets of data. After you remove the definition for the last set of signable data from the Data in the form that can be signed list, you must explicitly select the Do not enable digital signatures option before you can close the dialog box.

To enable digital signatures for part of the form by using the Form Options dialog box

  1. On the Tools menu, click Form Options.
  2. On the Digital Signatures tab, click Enable digital signatures for specific data in the form.
  3. Click Add to define a set of signable data.
  4. In the Set of Signable Data dialog box (Figure 3), set all the attributes necessary to uniquely associate the specification for the set of signable data with the data that you want users to sign. The specification for a set of signable data must include the following:
    • A unique name.
    • An XPath expression that defines the form data to be signed. For more information, see Specifying the XPath Expression for a Set of Signable Data.
    • The container node where InfoPath is to store all signature data.
    • The relationship between the signatures that can sign the set of data.
    • The message InfoPath displays to users before they add a signature.

The relationship between signatures on the set of signable data (Signature options) can be one of the following:

  • Allow only one signature.
  • All signatures are independent (co-signatures).
  • Each signature signs the preceding signatures (counter-signatures), or more explicitly, the first signature signs the data, and any subsequent signature signs the previous signature.

Figure 3. The Set of Signable Data dialog box 

To enable signatures for parts of a form, you must define at least one set of signable data, and you can define as many sets of signable data as you need.

InfoPath disables the ability to specify a group in which to store signatures in form templates that were not created with an open schema. For such templates, InfoPath creates the signature container node automatically and adds it to the schema that InfoPath autogenerates during form design. To specify this setting for a form template that was created with an open schema, you must start your form template design with a node that has a content model with a wildcard character in the XML Signatures namespace, as follows: "http://www.w3.org/2000/09/xmldsig#"

For a form that you configure for signing sets of data, InfoPath creates one container node for each set of signable data that you define. Each container node contains all signatures that are added to the assigned set of signable data. All signature container nodes are wrapped by another container node that is a child of the root node.

Enabling Conditional Formatting for Digitally Signed Data

When you enable digital signatures for parts of the form by using the Form Options dialog box, InfoPath does not disable the controls specified by the XPath expression defined for the set of signable data when the data is signed, although the associated XML DOM becomes read-only.

Figure 4 shows the message InfoPath displays when a user attempts to edit controls that contain data that is already signed.

Figure 4. Message that InfoPath displays when user tries to edit data in a signed control 

For InfoPath to disable a control after it is signed, each control specified by the XPath expression must have a conditional formatting rule that specifies when InfoPath is to disable the control.

To add a conditional formatting rule to a control

  1. Open the Properties dialog box for the control.
  2. On the Display tab, click Conditional Formatting.
  3. Click Add to define a new conditional formatting rule.
  4. In the first drop-down list of the condition definition, click Select Set of Signable Data.
  5. In the Select Set of Signable Data dialog box, select the set of signable data that you want InfoPath to disable after it is signed, and then click OK.
  6. In the second drop-down list of the condition definition, click is signed.
  7. Select Read-only as formatting.

Figure 5 shows the conditional formatting rule added to a set of signable data.

Figure 5. Conditional formatting related to digital signatures in MySignature set of signable data 

You cannot apply read-only conditional formatting to container controls such as sections or optional sections. You can apply it only to basic controls such as text boxes, check boxes, option buttons, and list boxes. You can, however, apply other types of conditional formatting to sections and optional sections that you configure for digital signing.

Enabling Signatures for Parts of the Form with the Section Properties Dialog Box

You can use the Section Properties dialog box to enable digital signatures for the set of controls contained within a Section or Optional Section control. These two container controls are the only ones that support digital signatures and the only ones you can configure for digital signing directly through their properties dialog boxes. The user interface for several features is available only through the Digital Signatures tab of this dialog box (Figure 6).

With the Section Properties dialog box, you can associate a set of signable data with a section. You can associate a set of signable data that you defined previously, or you can define the signable data when you define the association. With this dialog box, you can also enable one digital signature for all controls in an entire section. By default, all controls contained in the section become read-only when the section is signed. The XPath expression that defines the set of signable data associated with the section also defines the data that is signed when the section is signed. By customizing this XPath expression, you can add additional controls and data to the default set of data that is bound to the controls within the section. For more information, see Specifying the XPath Expression for a Set of Signable Data.

By default, when you use the Section Properties dialog box to enable digital signatures, InfoPath adds conditional formatting to disable editing in all the controls in the section after the data is signed. The When signed, make controls read-only check box controls this feature, and it is selected by default. Any controls you add to the section after you configure the digital signatures settings for the section do not have conditional formatting set, unless you clear and then select the When signed, make controls read-only check box. You can also manually set conditional formatting for individual controls, as described in Enabling Conditional Formatting for Digitally Signed Data.

The When signed, make controls read-only check box has three states:

  • Selected. All controls that exist in the section when you associate it with the set of signable data become read-only after the first signature is added.
  • Cleared. All controls that exist in the section when you associate it with the set of signable data remain editable after it is signed. However, the associated XML DOM becomes read-only after the first signature is added. At that point, no user can change any data bound to these controls, and InfoPath displays a warning message if any user attempts to do so.
  • Unknown. InfoPath cannot determine whether the controls in a section have associated conditional formatting to make them read-only after signing.
    Note   After you associate a section with a set of signable data for the first time, InfoPath displays the When signed, make controls read-only check box in the unknown state when you re-open the Digital Signatures tab of the Section Properties dialog box. This happens whether you configure all the controls in the section to have read-only conditional formatting or not. To determine the actual conditional formatting settings for controls within the section, you can preview the form, or you can use the Conditional Format dialog box to examine the conditional formatting settings for each of the controls.

Figure 6. Configuring a section control for digitally signing data 

Use the Digital Signatures tab of the Section Properties dialog box to:

  • Enable digital signatures for specific data in the form.
  • Define a set of signable data and associate it with the section. (If you do so when you have selected Enable digital signatures for the entire form in the Form Options dialog box, InfoPath changes that setting to Enable digital signatures for specific data in the form.)
  • Associate an existing set of signable data with the section.
  • Modify an existing set of signable data.
  • Select the When signed, make controls read-only check box, which adds conditional formatting to all controls in the section.
  • Select the Show signatures in the section check box to enable user interface icons and text that display in the form to show the digital signatures of the users who signed the section. When you select this check box, then after the section is signed, InfoPath displays an icon and link for each signature. By clicking a signature link, users can display the Verify Digital Signature dialog box that provides details about the signature and about the signed data.

When you use the Section Properties dialog box to associate a section with a set of signable data, InfoPath displays an icon and a Click here to sign this section link below the section when the user edits the form (Figure 7). When the user clicks this icon or link, InfoPath displays the Digital Signatures Wizard with which the user can select a digital certificate, sign the data, and then verify the signed data.

Figure 7. User interface elements that display in the form when you configure a section for signing data 

Table 2 summarizes the differences and similarities between enabling digital signatures in the Digital Signatures tab of either the Form Options or the Section Properties dialog box.

Table 2. Differences in Enabling Digital Signatures in the Digital Signatures Tab of the Form Options or Section Properties Dialog Box

ActionsForm Options Dialog BoxSection Properties Dialog Box Details
Enable digital signatures for specific data in the formYesYesForm must have at least one set of signable data.
Enable digital signature for the entire formYesNoSigns all data in the form, including data that is not bound to controls.
Disable digital signatures in the formYesNoNone
Add or modify the definition of a set of signable dataYesYesUse the Set of Signable Data dialog box.
Remove the definition of a set of signable dataYesNoAfter removing the last set of signable data, manually select the Do not enable digital signatures option.
Associate a section with a set of signable data, and enable the Click here to sign this section icon and link in the view for signingNoYesXPath expression defines signed controls.
Remove the association between a section and a set of signable dataNoYesRemoves only the association and the Click here to sign this section icon and link that appear below the control when editing the form. The definition of the set of signable data remains in the form, and form users can still sign the data by clicking Digital Signatures on the Tools menu or the Digital Signatures button on the Standard toolbar. Also, existing conditional formatting is not modified.
Show all signatures added to a section during editing NoYesClick the signature to display the Verify Digital Signature dialog box with signature details.
Make all controls read-only when signedNoYes (by default, InfoPath makes all controls within a section read-only after the section is signed)Use the Properties dialog box to change conditional formatting for individual controls contained within a section.
Mix read-only controls with editable controls after form is signedYesYesUse the Properties dialog box to change conditional formatting for each control.
Set the name and XPath expression automatically when you define a set of signable dataNoYes (by default, the name and XPath expression are set to the group that is bound to the section)None

Enabling Digital Signatures and Defining Signable Data in a Single Operation

You can enable digital signatures for the controls within a section and define the set of signable data in a single operation.

To enable digital signatures and define the set of signable data

  1. Design a form and add a Section or Optional Section control to the view. By default, the name of the group in the schema associated with this section is groupn, where n is an integer value.
  2. Place all required controls in the section. The elements bound to these controls are children of the group element created in step 1.
  3. Right-click the section, and then click Section Properties.
  4. On the Digital Signatures tab, select the Allow users to digitally sign this section check box.
  5. In the Sign the following data in the form when this section is signed drop-down list, select Add data that can be signed.
  6. In the Set of Signable Data dialog box, define the set of signable data that you want to associate with the section, as follows:
    • InfoPath provides a default name, but you can provide your own name. Regardless of how the name is defined, it must be unique, or InfoPath does not allow you to define the set of signable data.
    • InfoPath automatically creates an XPath expression with its value set to the current section by default. Typically, this value is the one you want to use, but you can change it by typing another value (for example, the expression /my:myFields/my:group1 | /my:myFields/my:MyCustomField1 signs the field named "MyCustomField1" together with the section named "group1"). Alternatively, you can create a value by clicking the Select XPath button and specifying the expression in the Select a Field or Group dialog box. For more information, see Specifying the XPath Expression for a Set of Signable Data.
    • Specify the signature type by using one of three option buttons: Allow only one signature, All signatures are independent (co-sign), or Each signature signs the preceding signatures (counter-sign).
    • Choose whether to change the value of the default message that InfoPath displays to the user in the Verify Digital Signature dialog box. For more information, see The Verify Digital Signature Dialog Box and Nonrepudiation Data.
    • Click OK.
  7. Set the desired value for the Show signatures in the section check box.
  8. Set the desired value for the When signed, make controls read-only check box.

Associating an Existing Set of Signable Data with a Section

You can associate an existing set of signable data with a section.

To associate an existing set of signable data with a section

  1. Design a form, and add a section to the view. By default, the name of the group in the schema associated with this section is groupn, where n is an integer value.
  2. Place all required controls in the section. The elements bound to these controls are children of the group created in step 1.
  3. On the Tools menu, click Form Options.
  4. On the Digital Signatures tab, click Enable signature for specific data in the form.
  5. Click Add, and then use the Set of Signable Data dialog box to define the set of signable data you want to associate with the section, as follows:
    • Provide a unique name that you have not used for any other set of signable data in the form.
    • Set the value for the XPath expression of the data that form users can sign. Type the XPath expression, or click the Select XPath button and then use the Select a Field or Group dialog box to specify the value of the expression. For more information, see Specifying the XPath Expression for a Set of Signable Data.
    • Specify the signature type by using one of three option buttons: Allow only one signature, All signatures are independent (co-sign), or Each signature signs the preceding signatures (counter-sign).
    • Choose whether to change the value of the default message that InfoPath displays to the user in the Verify Digital Signature dialog box. For more information, see The Verify Digital Signature Dialog Box and Nonrepudiation Data.
    • Click OK.
  6. Right-click the section, and then click Section Properties.
  7. On the Digital Signatures tab, select the Allow users to digitally sign this section check box.
  8. In the Sign the following data in the form when this section is signed drop-down list, select the set of signable data defined in step 5.
  9. Set the desired value for the Show signatures in the section check box.
  10. Set the desired value for the When signed, make controls read-only check box.

Specifying the XPath Expression for a Set of Signable Data

You define a set of signable data by specifying an XPath expression that identifies the data to be signed. You specify this XPath expression in the Fields or groups to be signed field in the Set of Signable Data dialog box. You can type this value, or you can click the Select XPath button to create the expression in the Select a Field or Group dialog box.

The XPath expression for a set of signable data follows the specifications of XPath expressions in an XML document. Table 3 shows examples of XPath expressions for signatures.

Table 3. Examples of XPath Expressions for Sets of Signable Data

XPath expressionDescription
/my:myFields/my:group1Signs the data in the node, including all child nodes (assuming that group1 is a container node).
/my:myFields/my:NameSigns the data in the node. This data can be bound to a text box or other basic control, or it can be the value of an attribute that may or may not be bound to any control in the form.
/my:myFields/my:group1 | /my:myFields/my:NameSigns the data in the node, including all child nodes, plus the data in the node. The data in the node can be bound to a text box or other basic control, or it can be the value of an attribute that may or may not be bound to any control in the form.
/Signs everything under the root node; that is, all nodes contained in the form's root node.
Note   InfoPath does not accept XPath expressions that use axes other than child:: or descendent:: or any expressions that use predicates.

To change or extend the definition of a set of signable data, you can modify the XPath expression that specifies the data to be signed.

To modify the XPath expression for a set of signable data

  1. If you are working with a section, right-click the section and then click Section Properties. If you are working with a set of data that you defined by using the Form Options dialog box, then on the Tools menu, click Form Options.
  2. On the Digital Signatures tab, select the set of signed data, and then click Modify.
  3. In the Set of Signable Data dialog box, edit the XPath expression.

To modify the XPath expression for a set of signable data to enable signing three sections in a form at once

  1. Add three sections to the form (either Section or Optional Section). By default, InfoPath names the corresponding nodes in the schema as group1, group2, and group3. Add the necessary controls to each section.
  2. On the Tools menu, click Form Options.
  3. On the Digital Signatures tab, select Enable signatures for specific data in the form, and then click Add.
  4. In the Set of Signable Data dialog box, type the name, MultiSectionSignature, and then type the following XPath expression (changing the group names, if you are not using the default names):
    /my:myFields/my:group1 | /my:myFields/my:group2 | /my:myFields/my:group3
    

    This XPath expression specifies a set of signable data that includes all three sections.

  5. For each of the three section controls bound to the groups in the XPath expression, perform the following steps:
    • Right-click the control, and then click Section Properties.
    • On the Digital Signatures tab, select Allow users to digitally sign this section, and then select MultiSectionSignature in the drop-down list.

After you perform these steps, you can see the Click here to sign this section icon and link following each of the three sections. When a user signs any one of these sections, all three sections are signed, and the signature appears after each section (assuming you selected the Show signatures in the section check box).

Notes

  • If no association exists between a section and a set of signable data, the drop-down list on the Digital Signatures tab of the Section Properties dialog box selects the first set of signable data in the list. You must choose the correct set of signable data or add a new one. If you accept the default set of signable data, then InfoPath displays the signature a user adds to that set of signable data for any other sections associated with that set of data. This is because the user interface display of a signature associated with a section is independent from the XPath expression that defines the data to be signed. You must take care to bind the correct set of signable data to the correct section control, depending on the signing scenario.
  • If you have not already defined an association between a section control and a set of signable data, the drop-down list on the Digital Signatures tab of the Section Properties dialog box displays the name of the previously associated set of signable data.
  • Because it is possible to specify data that is not bound to controls for digital signing, a user may be signing data that does not appear in the view. However, the Verify Digital Signature dialog box displays an image that is a snapshot of only the data that was visible in the view when the user added the signature. You should ensure that all significant data that the user is signing appears in the view, so that users can view it when approving the signature in the Verify Digital Signature dialog box. For more information, see The Verify Digital Signature Dialog Box and Nonrepudiation Data.

Identifying Signed Data in the View

When a user fills out a form, the user may point to or attempt to select a control or set of controls that contains data that is signed. If this happens, the signed control displays an icon in the upper right corner that indicates that the data bound to that control is locked and cannot be changed. InfoPath does not display this icon if you have configured the entire form for signing; instead, InfoPath disables the entire form. Figure 8 shows the icon indicating that the MySignedData text box control is signed and locked.

Figure 8. A signed text box control

Understanding the Digital Signature Status and Verification Process

While editing a form, a user can click Digital Signatures on the Tools menu or the Digital Signatures button on the toolbar to display a list of the digital signatures in the form in the Digital Signatures dialog box. The Status column in the list displays one of the values shown in Table 4 for each signature.

Table 4. Digital Signature Status Values

StatusDescription
ValidThe signed data and the attached signature data have not been changed since the data was signed. The signature verification operation was successful.
InvalidThe signed data or the attached signature data has been tampered with.
ErrorThe data contained in the Signature element or the signature template itself is malformed, or some other error occurred during verification. In other words, the signature is cryptographically valid, but either it does not conform to the XML Signature standard, or it contains data in a format that InfoPath does not support.
RevokedThe digital certificate used to sign the data has been revoked.
Not TrustedThe digital certificate used to sign the data is not trusted, because no chain of trust can be identified.
ExpiredThe digital certificate used to sign the data is expired.

The Status value displayed in the Digital Signatures dialog box results from a combination of the signature status (which can be valid, invalid, error, or unsupported) and the certificate status (which can be valid, error, revoked, not trusted, or expired), where the certificate status takes precedence over the signature status. For example, if the signature status is Valid (the hash of the signature indicates that the signature and the signed data have not been tampered with), but the certificate status is not trusted, InfoPath displays the combined status as Not Trusted. You can work programmatically with the Status property of the Signature and Certificate objects to access the status of the signature or certificate independently. To see a code sample that shows how to do this, see Building a Task Pane for Displaying Information about Digital Signatures.

Figure 9 shows the signature status as displayed in the Status column of the Digital Signatures dialog box. Figure 10 shows a signature status message that InfoPath displays when the user attempts to apply an invalid signature while editing the form.

Figure 9. Signature status displayed in Status column of Digital Signatures dialog box 

Figure 10. Invalid signature status message displayed during editing 

When you click the View Signed Form button in the Digital Signatures dialog box, InfoPath displays the Verify Digital Signature dialog box. This dialog box provides more detailed information about the state of the form when it was signed and the computer on which it was signed. When you click the View Certificate button, InfoPath displays the Windows Certificate dialog box, which provides details about the certificate used to sign the data.

You can also access the status of the signature or the certificate through the digital signatures object model. For more information, see Using the InfoPath Object Model to Work with Forms Configured for Signing Data.

The InfoPath infrastructure verifies the digital signatures in the form at the following times:

  • When the user loads the form.
  • When the user saves the form.
  • When the user submits the form.
  • When the user adds a signature to the form.
  • When InfoPath displays the Digital Signatures dialog box in response to the Digital Signatures command or button, or because InfoPath calls the ShowSignatureDialog method of the UI object.
  • When InfoPath calls the Sign method of the SignedDataBlock object from the OnSign event handler.

When a user loads your form, if InfoPath cannot identify any of the signatures in the form as valid, it displays a warning message.

When a user edits your form, in the form view, InfoPath replaces the name of an invalid signature with the following text, in red: "There is a problem with this signature".

InfoPath shows digital certificates that have a status of Not Trusted as available for use in signing, but such certificates create signatures that display the Not Trusted status. InfoPath does not show expired or revoked certificates as available for use in signing.

The Verify Digital Signature Dialog Box and Nonrepudiation Data

InfoPath stores the following additional nonrepudiation data with the signature and displays it in the Verify Digital Signature dialog box (Figure 11):

  • An image of the current view as a Base 64-encoded Portable Network Graphics (.png) file that InfoPath captured when the user created the signature. You can use this image to verify the state of the form as the user saw it when signing.
  • The status of the signature with details.
  • Any comments the user added when signing the form.
  • A message you defined (InfoPath displays this message only when the user is verifying the signature in the next-to-last panel of the Digital Signature Wizard).
  • Information about the certificate the user used to create the signature. You can see this information by clicking the View Certificate button in the Verify Digital Signature dialog box.
  • The system date, time, and time zone when the user signed the data.
  • The versions of Windows, Microsoft Office, and InfoPath in use when the user signed the form.
  • The number of monitors and the resolution of the primary monitor.
  • The form template fingerprint, which is a cryptographic hash value of the form template. InfoPath uses this value to identify any changes a user makes to the form template that may cause the signed data to display differently or have a different meaning. InfoPath does not display this value when you preview the form.
  • The name of the view that InfoPath displayed to the user when the user added the signature.

The form user signs

« July 2010 »
Su Mo Tu We Th Fr Sa
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

search


recently...

archives

Categories

my Links

Syndicate

  • RSS 0.90
    RSS 1.0
    RSS 2.0
    Atom 0.3