Standing on the shoulders of giants. RSS 2.0
# Wednesday, May 28, 2008

Meet me in Los AngelesA preliminary list of technical sessions has been announced and the registration has been opened for PDC 2008. Some of the interesting sessions:

Architecting Services for the Cloud
From design to implementation, building a scalable, available web service is different from building other kinds of applications. This session will discuss the impact that designing for the cloud has on all stages of the service lifecycle, and how Microsoft's cloud platform works for you to meet the scaling and availability goals of your service

Logical Queuing: Developing Occasionally Connected Clients
With Sync Services for ADO.NET, Sync Framework, etc., what technology should you use to develop applications that enable end-user productivity regardless of network connectivity? The reality is no one technology solves the problem. We will demonstrate how you can build offline-capable rich client applications by combining technologies like ADO.NET and SQL Server Compact Edition with the Microsoft Sync Framework. Next we take an architectural approach for "using the right tool for the right job" and show how many of these technologies actually work best when brought together in a cohesive solution that highlights the values each technology has to offer.

Under the Hood: Architecture of Storage in the Cloud
Get a deeper understanding of the storage architecture and understand how the storage platform can be used to the best of its capabilities. From low-level streams all the way to partitioned tables, cloud storage must be designed and optimized for the scaling demands of the cloud. This session will examine the underlying architecture of each layer of the storage service as well as the data modeling and programming interfaces exposed.

Under the Hood: Building SQL Server Data Services
Learn how we built SQL Server Data Services to address hard distributed systems and operations challenges. We will describe how we solved problems like failure detection, leader election, and automatic failover using a new innovation called Distributed Data Fabric. We will go deep and elaborate on the changes we made to the core SQL Server RDBMS to ship this massively scalable data service. We will also describe the operational systems we use to provision, monitor, and manage SSDS without interrupting the service. Finally, you will learn how we manage and run this service in our datacenters.

The rest of the sessions can be found on the Microsoft PDC 2008 site.

Wednesday, May 28, 2008 2:22:23 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Conference | PDC2008
# Wednesday, May 14, 2008

Recently I finished 2 books about programming with the Windows Presentation Foundation (WPF), "Programming WPF 2nd edition by Chris Sells & Ian Griffiths" and "Essential Windows Presentation Foundation by Chris Anderson". Both books offer a great introduction to programming WPF, but I think "Programming WPF" is the better book.

Programming WPFThe first obvious difference is the difference in size between both books, Programming WPF with its 835 pages dwarfs Essential WPF pages with (only) 458 pages. After the foreword, the first chapter of both books gives you a tour of WPF and an introduction on the topics that will be covered in each. Here the difference all ready shows, the additional pages in Programming WPF have not only been used to go into more detail the subjects covered in both, but also covers additional subjects like: 3D and Silverlight (by Shawn Wildermuth).

Essential WPF

The thing makes Essential WPF a very interesting book nonetheless, is that because it's written by one of the architects of the WPF team it gives insight in why some choices are made, where Programming WPF is more a book which describes how to do things (often far better than the documentation).

In the end I am very happy I read both books. Initially I wasn't going to read this edition of Programming WPF because I read the first edition and had Essential WPF and the Petzold book in my reading stack. But after reading it, this book is huge addition to the first edition by covering more subjects and updating all code to the final version.

If you are only buying one book about WPF buy Programming WPF; if you are interested in some of the architectural choices you should also buy Essential WPF. Hopefully both books will soon have an updated version which will cover the changes made to WPF in .NET 3.5 and .NET 3.5 SP1.

Note: a review of "Application = Code + Markup by Charles Petzold" is coming as soon as finish reading it.

Wednesday, May 14, 2008 1:59:32 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Reading | WPF
# Tuesday, April 29, 2008

Sample code to get the first day of the week given a date and a DateTimeFormatInfo.

public static DateTime StartOfWeek(DateTime date, DateTimeFormatInfo dateTimeFormat) {

    Debug.Assert(dateTimeFormat != null, "dateTimeFormat != null");
    if (dateTimeFormat == null) {
        throw new ArgumentNullException("dateTimeFormat");
    }

    DayOfWeek currentDay = date.DayOfWeek;
    DayOfWeek firstDay = dateTimeFormat.FirstDayOfWeek;

    int difference = (int)firstDay - (int)currentDay;

    // we always have to move back, 
    // since we're interested in the first day of the week
    if (difference > 0) { difference -= 7; }

    return date.AddDays(difference);
}

 

The attached sourcefile contains the testcases. StartOfCurrentWeek.cs.txt

Tuesday, April 29, 2008 9:47:31 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Codesnippet
# Monday, April 28, 2008

Recently a client wanted to import binary files with metadata into SharePoint 2007 from a directory. Because BizTalk was available and I suspected there would be some scaling issues if I would go the custom NT service route, I decided to prototype the solution in BizTalk first. The prototype was finished in just 2 days, which is a lot faster than a custom solution which is as scalable and reliable.

Customer question

The customer wanted to import scanned documents and metadata from their OCR scanners into a SharePoint document library. A scanned document consists of a PDF file and an XML file with the OCR results, both files have the same name (with a different extension) and are uploaded to a fileshare.

Solution

The solution consists of a BizTalk server which uses a File Receive Adapter to monitor a specific directory for a combination of a PDF and XML file, those are combined in an orchestration and send to a document library using the WSS Adapter.

Import Process 

The BizTalk solution consists of several pieces:

  1. A schema to describe the received XML file,
  2. An orchestration, to receive the files, create the new message and send that to the document library,
  3. A pipeline component to rename the received files (and 2 pipelines to host it),
  4. A custom component to encode the values send in the metadata.

The schema

The schema can be any valid XML-schema, but to make it easier to add the properties to the WSS message I set the type of the nodes to string and promoted them. Note that if some of the fields are nullable, we have to take care when accessing those.

The orchestration

The orchestration consist of 3 steps:

  1. Receiving the file,
  2. Creating the new message,
  3. Sending the message.

Step 1: Receiving the file

 receive

There are 2 receive ports, one for each of the file types, both match to a receive action and are able to start the orchestration. Between the receive actions exists a correlation, which correlates the received messages on their (normalized) filename. The filenames are normalized using a custom pipeline component, see below. Only when both ports have received a file the next step of the orchestration is started.

Step 2: Creating the new message

Create message

Creating the message consists of 2 steps to make it easier to organize the code. In the first step, "SetWssProperties", a global variable is filled with a string containing an XML node with the custom properties send to SharePoint. All values are encoded using a custom component, the PropertyEncoder, see below.

WssProperties = "" 
+ "Team" 
+     ""+ Paulb.PropertyEncoder.Encode( InvoiceXml.fields.Team ) + "" 
+     "Client" 
+     ""+ Paulb.PropertyEncoder.Encode( InvoiceXml.fields.Client )+ "" 
+     "Document_x0020_type" 
+     ""+ Paulb.PropertyEncoder.Encode( InvoiceXml.fields.DocumentType )+ "" 
+    "Gross_x0020_amount" 
+     ""+ Paulb.PropertyEncoder.Encode(InvoiceXml.fields.TotalAmount) + ""; 
if( false == System.String.IsNullOrEmpty(InvoiceXml.fields.InvoiceDate)) {
      WssProperties = WssProperties + "Invoice_x0020_Date" 
      + ""+ InvoiceXml.fields.InvoiceDate + ""; 
}

WssProperties = WssProperties +    "Invoice_x0020_Number" 
+     ""+ Paulb.PropertyEncoder.Encode( InvoiceXml.fields.InvoiceNumber )+ "" 
+    "ScanID" 
+     ""+ Paulb.PropertyEncoder.Encode( InvoiceXml.fields.ScanID )+ "" 
+    "Vat_x0020_number" 
+     ""+ Paulb.PropertyEncoder.Encode ( InvoiceXml.fields.VatNumber )+ "" 
+ ""; 

In the second step, the incoming PDF message is copied to the outgoing WssMessage and it's properties are set. The filename is encoded using the custom ProperytEncoder component to meet the requirements for a filename in a SharePoint Document Library.

InvoicePdfMetaData = InvoicePdf;
InvoicePdfMetaData(WSS.Filename) = "FLT" + Paulb.PropertyEncoder.EncodeFileName(InvoiceXml.fields.ScanID) + ".pdf";

InvoicePdfMetaData(WSS.ConfigPropertiesXml) = WssProperties;

Step 3: Sending the message

Send Message

Sending the message is the final and simplest step: create a Send object and link it to the port. The configuration of the port is done using BizTalk Administration Console after deploying the solution to the BizTalk server.

The Pipeline

The solution involves 2 receive pipelines, one for each of the filetypes (xml and pdf). It is necessary to create 2 pipelines because the pipeline for the xml file requires the XML disassembler to recognize the schema and match it to the receive action. Both pipelines contain the custom FixFileName component, which normalizes the filename for the incoming file (it removes the path and the extension).

The actual work is done in the Execute method of the IComponent interface, the remaining interfaces either must be implemented, but are not used (IPersistPropertyBag) or are used by the designer environment (IComponentUI). The IBaseComponent interface supplies basic information about the component, such as Name and Version.

IBaseMessage IComponent.Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{

    // make sure we have something to work with
    if (pInMsg == null)
    {
        return pInMsg;
    }

    string receivedFileName = pInMsg.Context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties") as string;
    if (string.IsNullOrEmpty(receivedFileName))
    {
        // nothing we can do
        return pInMsg;
    }

    string newFileName = Path.GetFileNameWithoutExtension(receivedFileName);

    pInMsg.Context.Promote("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties", newFileName);

    return pInMsg;
}

One thing to remember, is to Promote the property you're writing otherwise you're not able to use it for routing.

Another thing about pipeline components is: BizTalk expects them to be deployed to a specific location on the filesystem, the Pipeline Components directory of the BizTalk installation directory (the default location is: C:\Program Files\Microsoft BizTalk Server 2006\Pipeline Components).

FixFileName.cs

Custom component for encoding properties

The component for encoding the properties is a standard .NET assembly. It is not necessary to implement any interfaces, all assemblies work when they are referenced in the BizTalk orchestration project. The only requirement is that the assembly is deployed to the GAC.

This project required some additional encoding of the XML values, beside the normal HTML encoding, to encode the characters used by BizTalk macros and to strip characters which are illegal in filenames in a document library.

PropertyEncoder.cs

See also:

Information about convoys

Developing pipeline components

Monday, April 28, 2008 10:25:18 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
BizTalk | Development | Sharepoint

Today we released the 1.0 version of the Euro 2008 Webparts for SharePoint 2007 and 2003.

These webparts allow you to host a Euro 2008 game on your SharePoint portal. The game consists of 2 webparts (there is a version for SharePoint 2003 and 2007), which allow the participants to predict the results of all the matches of the Euro 2008 Championship. The webparts connect to a webservice hosted by Tam Tam where the results of the matches and the scores of the participants is managed.

Other features include:

  • Overview of the next 10 matches.
  • Overview of all Euro 2008 matches.
  • A leaderboard of all users. The top 15 users with the highest points and the points of the current user.
  • View the details of a participating country with all the matches.
  • Multilingual. The web parts can be displayed in the following Languages: English, Dutch, German, French, Portugese and Spanish.
  • The end results of matches are hosted and administered by Tam Tam. You do not have to do anything to update scores.
  • All data stored on the Tam Tam servers is hashed.

Download the webparts from the Euro 2008 Webpart site.

Some screenshots:

Upcoming matches:

View upcoming matches

View a match and enter your prediction:

view match and enter prediction 

View country details:

View country details

Monday, April 28, 2008 1:52:45 PM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Fun | Sharepoint
# Monday, April 07, 2008
class Program {
    static void Main(string[] args) {

        string[] strings = { "aa", "bb", "c", "dddd", "eeee", "f" };

        // use a class which implements IComparer
        // This works best when you want to re-use sorting logic
        //  or need to store state between using the comparer.
        Array.Sort(strings, new StringLengthComparer());

        // The following two methods only differ in syntax, both use a delegate.

        // use an anonymous method
        Array.Sort(strings, delegate(string x, string y) { return x.Length - y.Length; });

        // use a lambda expression
        Array.Sort(strings, (x, y) => x.Length - y.Length);

    }

    class StringLengthComparer : IComparer<string> {

        public int Compare(string x, string y) {
            return x.Length - y.Length;
        }
    }
}

Note: The array is sorted on the length of the strings, if you want to sort the strings in the array based on the content use an instance of the StringComparer class.

Monday, April 07, 2008 9:42:29 AM (W. Europe Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
C# | Codesnippet
# Wednesday, March 26, 2008
# Monday, March 03, 2008

This class is an addition to the html- and url-encoding in the HttpServerUtility class. Where the methods in the base framework, only encode a limited number of characters. The classes in the AntiXss class encode everything, that is not explicitly allowed. These means that everything but the following characters are encoded in most cases: a-z, A-Z, 0-9, (comma), (period), (dash), (underscore) and (space). 

[download: Microsoft Anti-Cross Site Scripting Library V1.5]

Monday, March 03, 2008 5:55:07 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [0] - Trackback
C# | Security
# Thursday, February 14, 2008

[Note: most of this post discusses document libraries, but the concepts and code are similarly applicable to other types of lists.]

The default "New" menu item in a document library has just 2 items: document and folder.

New menu

Changing these options in the UI is relatively easy, after enabling the management of content types and  adding a number of content types to the document library these automatically appear in the menu.

extende new menu

The document library settings even allow you to change order of the content types and hide content types from the New menu. ( Shared Documents > Settings > Change New Button Order )

  New button manager

The next step is managing these settings from code, so you can easily change the settings in multiple document libraries. Investigating the SPList class you notice the ContentTypes property, this method returns a collection of supported content types for a list. Deleting a content type from this list, removes the support for that content type from the document library. This will throw an exception when the content type is still in use by items in the list.

// open the library
SPList lib = GetDocumentLibrary();
SPContentTypeCollection contentTypes = lib.ContentTypes;
SPContentType contentType = contentTypes[ /* content type name */ ];
if (contentType == null) {
    // content type not found
    return;
}
// delete the contentype
contentType.Delete();

lib.Update();

Adding a content type is similar:

contentTypes.Add( new SPContentType( /* */ ) )

Changing the order of and hiding content types is less simple. The SPContentType class has a Hidden property, but this property does not appear to have an effect on the content type. But there is another place in an SPList where content types are managed, the RootFolder property has 2 properties: ContentTypeOrder and UniqueContentTypeOrder. The ContentTypeOrder property contains all the content types supported by this list and return the content types from the parent when the list has not specified unique content types. The UniqueContentTypeOrder is used to specify the unique content types for the new menu and their order.

// open the library 
SPList lib = GetDocumentLibrary(); 

IList<SPContentType> currentOrder = list.RootFolder.ContentTypeOrder;
List<SPContentType> result = new List<SPContentType>();
foreach (SPContentType ct in currentOrder)
{
    if (ct.Name.Contains("Document"))
    {
        result.Add(ct);
    }
}

list.RootFolder.UniqueContentTypeOrder = result;
list.RootFolder.Update();

So managing the items in the new menu, is possible but it's not very straightforward.

Thursday, February 14, 2008 5:22:26 PM (W. Europe Standard Time, UTC+01:00)  #    Comments [1] - Trackback
SharePoint
About
© Copyright 2008
Paul van Brenk
Sign In
newtelligence dasBlog 2.3.8275.16006
All Content © 2008, Paul van Brenk
DasBlog theme 'Business' created by Christoph De Baene (delarou)