Welcome to MSDN Blogs Sign in | Join | Help

saurabhd's musings

Saurabh Dasgupta works for Microsoft Consulting Services. - '640kb ought to be enough for anybody'
Powershell:Reading the header columns in a .CSV file using import-csv cmdlet

As my journey into the wonderland of Powershell continues, I stumbled upon the need to read the list of header columns from a .CSV file. You would have already used import-csv to read the content of a .CSV file. What a beauty! If you need to know the column headers in the file, you can try this approach:

$headers=import-csv sample.csv |  gm -member noteproperty
foreach ($headerline in $headers)
  {
  out-host -Inputobject $headerline.name
  }

I thank my colleagues at Microsoft for giving me this tip.
Comparing the processing power of servers in your Performance testing farm

Think of this  scenario. You are into a performance tuning engagement.  You are given two servers which are supposed to be playing the role of hosting ASP.NET applications.

You implement load balancing. You test the servers  for distribution of web requests. All has gone well so far. Now time for the acid test. You perform a load test on your server farm by gradually increasing the client injected load. What do you see? After a point, the web servers are not evenly loaded anymore. The performance counter traces shows that one of the % Process Time\_Total for one of the servers reaches 95% while the other server is at less than 55%. It is not uncommon to have some disparity between the CPU utilization of the servers. However, the difference in this case warrants further investigation.

You report back to your customer and the infrastructure team tells you that both the servers are  of
'near' identical make and hence they should be performing equally well. You take their word. You are convinced that there is something wrong with the application and start digging in to find the 'root cause'.

Hours turn to days and days to weeks and still no results! If you have faced such an experience then please read on.

The possibility of a rogue process or driver consuming undue processor cycles arose. Running Xperf and Process Explorer eliminated this possibility.

Benchmarking the CPU using simple Random number generation


If you are not a hard core infrastructure specialist like me then interpreting the finer details of the hardware specifications can become a challenge. It is a good idea  not to completely trust the hardware specifications. So, I thought of doing some elementary number crunching tests on each of the servers to get an idea of how they perform. I began with writing a console application that generates Random numbers in a multi-threaded fashion for a  pre-configured amount of time. I ran my tool on both the servers and was surprised that one of the IIS boxes  generated less than half of the random numbers  when compared with the other server. This was a complete revelation and began to explain my observations during the prior stress test. It was exciting to watch how the CPU utilization grew across all the processors as and when the thread count was increased. My suspicions that the underperforming server was CPU deficient by design, grew stronger. I was  conscious that generating Random numbers is just one of the many workloads  profiles possible and this may not necessarily be a representation of my ASP.NET application. We would need a tool that would stress the CPU under various work profiles. At this point my colleague suggested that I try the CPU benchmarking tool from PassMark.

Using the PerformanceTest 7.0 tool from PassMark

I used the CPU and Memory tests option from this tool. The tests gave me results in the following category:

CPU

  1. CPU Integer Math   
  2. CPU Floating Point Arithmetic   
  3. CPU Find Prime Numbers   
  4. CPU Multimedia Instructions   
  5. CPU Compression   
  6. CPU Encryption   
  7. CPU Physics   
  8. CPU String sorting

Memory

  1. Memory -Allocate SmallBlock   
  2. Memory - Read Cached   
  3. Memory-Read Uncached   
  4. Memory - Write   
  5. Memory - Large RAM

After executing this tool on each of the application servers, I plotted the results in Excel chart to get a better idea of the servers stack against one another. It is important to have a good understanding of the what each performance metric implies. The product documentation does provide some insight, however I would have expect much more detailed information so that my results would be more credible.

 

 

Disclaimer

The opinion expressed in this message are entirely personal and not necessarily supported by Microsoft. I am not an employee of PassMark software and I have no contractual obligation with PassMark software.

Querying SQL server from Powershell scripts

I was trying to figure out a way to invoke custom SQL queries from a Powershell script and process the data within the script. I wanted something more powerful than executing queries from SQLCMD.EXE. My scenario required me to take an action based on the value of a particular row in the table. I got the answer after a bit of trawling the internet. -:)

Here is an example:

 

 

###############################################################################
#
#
# This script queries the LoadTestCase table of the VSTT database 
# As an example, the script iterates through all the data rows in the datatable
# 
###############################################################################


  $databasename="LoadTest"
  $dbserver="localhost\sqlexpress"
  $cnstring="Data Source=$dbserver;Integrated Security=SSPI;Initial Catalog=$databasename"
	$sqlcn = new-object system.data.SqlClient.SqlConnection($cnstring)
	$ds = new-object System.Data.DataSet "dsVSTT"
	$query = "select * from LoadTestCase"
	$adapter = new-object "System.Data.SqlClient.SqlDataAdapter" ($query, $sqlcn)
	$adapter.Fill($ds)
	
	$dtMyInfo= $ds.Tables[0]
  
  
  foreach ($dr in $dtMyInfo.get_Rows())
    {
    write-host $dr[3]
    write-host $dr["TestCaseName"]
    }

#Export the contents of the datatable to a CSV file
remove-item -path output.csv -force
$dtMyInfo  | export-csv -path output.csv
Powershell - Your friend for Performance Testing projects

I am into an intensive performance testing project, one of the activities involves load testing Web services using Visual Studio Team Edition for Tester. The performance rig has 2 web servers, 2 database servers and 4 BizTalk servers. Writing the unit test for the web service and then authoring a web service was no big deal. The real challenge came when I had to carry out several house keeping tasks ,such as the ones listed here and consistently execute these tasks for each performance test run:

  1. Clear the event logs from all the servers in the rig before the load test commences
  2. Prior to the test, take a snapshot of a custom database by running a custom a query from a .SQL file
  3. Prior to the test, run a custom query on the custom databases which will tabulate the disk space in use by each of the file groups
  4. When the load test is complete, take another snapshot of the database by running a custom a query from a .SQL file
  5. When the load test is complete, take a backup of the event log from all the servers in the rig and save it as a .CSV file in the test results folder

 

I could achieve all of the above with custom .BAT/.VBS files. However, I found myself repeatedly adding references to different servers all across my scripts. This would become a larger challenge if I had to transport the complete performance testing solution, along with the .BAT/.VBS files to my customer's data center.

To solve this crisis, I adopted the strategy outlined below:

A common list of all servers in the farm

Maintain a .CSV file that contains the list of all the servers in the farm. I stress on CSV because the Import-Csv cmdlet makes it so easy to read the information from a file (example). Therefore, I ended up creating a CSV with the name: RigConfig.csv which had a structure like:

SERVERID,SERVERNAME, SERVERROLE,

b1,BIZTALK01 ,B
b2,BIZTALK02,B
w1,IIS-1,W
w2,IIS-2,W
d1,SQL01,D
d2,SQL02,D

 

Clearing event logs, installing Performance Counter logs, etc.

My Powershell scripts for clearing the event logs were coded around reading the entries in the file RigConfig.csv. You will notice that I have a column called SERVERROLE.The purpose of this column was to create Performance logging sessions from files that listed standard counters. I had a Powershell script that used Logman.exe to create Performance Counter capturing session by reading the appropriate role specific text file.

 

Executing the script from Visual Studio Team Edition for Testers

VSTT makes it very east to execute scripts immediately before a load test begins execution. Worked like a charm!

Moving from one rig to another..

While re-using the scripts from my lab environment to the customer's environment, I had very few changes to do.  Bulk of the changes were to RigConfig.csv

Snapshot of the event logs on all the servers in the rig

I faced the challenge of preserving a snapshot of the event logs immediately after each test run. I was doing this task manually, however it became tedious and error prone while doing this every time for my 6 servers in the farm. To read the event log I used the .NET object EventLog to read the local and remote logs. I ended up writing a Powershell function which read my RigConfig.csv and dumped the Application log from each of the servers into a text file. Job done!

 

Conclusion

If you have been mulling about Powershell but not switched as yet because of the initial overheads, I sincerely suggest you make the cross over now. The rewards are plenty in the long run.

An approach towards implementing information entry forms using Silverlight and SharePoint-Part 2

Recap of Part 1

This is a continuation of Part 1 of the article. In the first part we discussed about a Expense entry form created using Silverlight. We discussed how it could be hosted on a dynamically created SharePoint page (web part page) using a generic Silverlight Application web part. We uploaded the .XAP file to a custom Document Library and configured the Web Part's properties in the Design Mode of the form so that it reads the XAP file from the custom document library with the appropriate dimensions.

 

What do we intend to achieve?

In this post, we will go a couple of steps forward and examine how we can accomplish the following:

  1. Submit the Expense information (serialized as XML) from the Expense Data Entry form to a custom document library (call it ExpenseData library )
  2. Author a workflow using SharePoint Designer and assign it to ExpenseData library so that an approver is automatically assigned an approval task. This is also followed by a mail being sent to the approver.
  3. When the approver views the approval task, possibly display the submitted expense data  (XML) in a read-only view using the same Silverlight application

We will create a simple workflow using SharePoint Designer. We will also modify the DispForm.aspx application page using SharePoint Designer and make it host our Silverlight Web Part.

By doing this, we want demonstrate how we can realize the potential of WSS/MOSS as a platform for building applications that reside in the Cloud. Can we build Rich Internet Applications using Silverlight by using WSS/MOSS and without the need for physical access to the server and without requiring administrative access to the physical server. I am quite confident that Silverlight complements the power of SharePoint thereby turning it into a platform for not just building HTML emitting portals , but powerful applications with CRUD like capability. I imagine a world where an enterprise would chose to fulfill the demands of their intranet portals using SharePoint and Silverlight. Mundane business processes like Holiday Management, Expense Submission, Feedback forms, etc. would be made from Silverlight and hosted out of a SharePoint farm, gradually taking over the place of custom ASP.NET applications.

 

Step 1 : Enhance the generic Silverlight Application Web Part

In Part 1 of this article we create a simple Web Part which encapsulated the Silverlight ASP.NET server control. We exposed a Source property so that the path to the .XAP file can be customized during Page design time. We also exposed a property of type String which could be configured during Page edit time to pass custom arguments into the Silverlight Application (as a series of Name-value pairs).

We will retain the Source property and InitParams the way they are. However, we will add one more property to the  Web Part. This will be of type ParametersCollection. This property will let us do things like pass request variables from the custom pages as parameters into the Web part and the Silverlight application.

Step 2 : Host the Expense Entry Silverlight app as a Web Part

As we did in Part 1,

  1. Create a custom document library to host the Silverlight application (.XAP file) . Call this library as XapLib
  2. Create a Web Part page which would be used for hosting the Expense Data Entry form
  3. Add an instance of our Generic Silverlight Web Part into this Page
  4. Configure the Source property of the Web Part so that it points to the .XAP file uploaded to the XapLib library

 

We need to configure the Expense Data form so that it knows where the expense information is to be submitted. We will modify the Expense Data form so that it can be configured with initialization arguments.

image

 

Of all the parameters required by the Silverlight Expense Data Entry form, one of them is named serviceurl.This is the URL of the web service which would be invoked for submitting the Expense information.

 

We will configure the Web part to inject a value for the named parameter serviceurl into the Expense Data Entry form

image

Clicking on the ellipses button displays a multiline text box for setting the Initialization parameters. Note that we are setting the URL of a custom web service and also the GUID of the document library where the Expense information will be saved. The GUID is one of the parameters into the web service, the other being the expense XML information

image

Step 3 : Submitting the Expense information to a custom Document Library

To interact with SharePoint document libraries I have written two Web services and hosted them in the ISAPI folder. Guidelines for developing SharePoint web services are available here.

  1. Service for uploading Expense XML information to a document library. This service will be called from the Silverlight application when the user clicks on 'Submit Report' button on the form
    1. image
    2. docllibid: GUID of the document library for posting the expense information
    3. documentname: display name of the submitted XML stream
    4. file: the raw XML stream
    5. On success the numeric ID of the submitted document is returned
  2. Service for reading the Expense XML information from a document library, given the ID of the document
    1. image
    2. documentid: The ID of the XML document that was submitted to the document library by using the first web service
    3. doclibid: The GUID of the document library where the expense XML document has been posted
    4. On success, the Byte array of the XML is returned

 

Step 4 : Create a simple Approval Workflow using SharePoint Designer

We will chose SPD as a means of authoring a simple workflow. The workflow will use the Collect Data from an User activity to gather Approve/Reject response from the the approver. The detailed steps are beautifully explained in  this article.

6. wizardscreen_step2_CollectDataFromUser

 

The crux of the Collect Data from an User activity is the code generated ASPX form which would be displayed to the approver.

image

When the approver is presented the above web page, he/she can view the details of the document by clicking on the encircled hyperlink. This link will take the user to the DispForm.aspx of the Expense Data document submission library.  However, we need something on DispForm.aspx that can render our custom XML and show meaningful expense to the approver.

Step 5 : Modify out-of-box DispForm.aspx to view submitted Expense data using our Silverlight app

Use SharePoint designer and navigate to the Expense Data document library in the Folder view.

image

I have modified DispForm.aspx so that it displays our generic Web Part. The Source points to the location of the .XAP file. The Web part Parameters collection allows for passing the ID of the document into the Silverlight web part using the QueryStringParameter object.

image

Conclusion and Challenges ahead of us

  1. In this article, I  demonstrated the basic steps required for leveraging Silverlight for building data entry forms, using SharePoint for hosting the application and also routing the submitted business information
  2. The marriage of Silverlight and Sharepoint offers a promise of rapidly constructing rich business forms without worrying about the physical web server or custom ASPX pages.
  3. I do not think we would be over imagining if we think of SharePoint as the Cloud within the company where all the applications of the enterprise will reside
  4. In subsequent posts I will deal with the how the workflow can interact with external applications. E.g. We want to save the Expense data into a LOB application once it has been approved.

Disclaimer 

The ideas expressed in this article are solely of the author and may not represent the views of Microsoft

 

An approach towards implementing information entry forms using Silverlight and SharePoint-Part 1

Introduction

Enterprises are regularly challenged with implementing custom user interfaces for capturing all sorts of internal information. Technically this could be achieved by creating custom ASP.NET web pages and recording the information in a Line of Business database. In this article , I have envisioned a solution which marries the RIA capabilities of SL and the portal/document management features of Windows SharePoint Services 3.0 (or even MOSS since it is built on WSS 30). Silverlight 2.0 is a powerful tool for building Rich Internet Applications. Silverlight comprises of a client side runtime which is hosted as an ActiveX control when using IE. The runtime downloads the specified .XAP file (ZIP) containing .NET assemblies and executes the compiled instructions within the assemblies.  SharePoint on the other hand provides an infrastructure for creating dynamic web pages which could be edited in-place or composed out of web parts. The outcome of this union offers a powerful solution to accomplish the following:

  1. Developing user interfaces using Silverlight for the purpose of information entry
  2. Storing the form templates (XAP files) in a document library for re-use across the enterprise
  3. Designing a re-usable SharePoint Web Part which would be responsible for rendering the XAP file at runtime
  4. Submitting user information to a custom document library and initiating a workflow to further process the submitted information
  5. Make this process easily repeatable without the business owner ever having to physically touch the application servers (servers running the WSS web front ends). Think of an organization with over 5000 employees. We do not want the business user(s)  running to a the IT administrator asking them for physical access to the web servers. We want the solution to be as close as possible to 'Software as a Service' paradigm.

 

Scenario:Expense Report Submission

image

This is an example of a very typical Expense data entry form. The steps for this scenario are as follows:

High level solution

  1. The employee would browse to an Intranet self service portal and select Business Expense Form. This would open up a data entry page.
  2. Employee would fill in the relevant details by adding line items for each business expense.
  3. Upon submission the the data will be saved centrally and a long running workflow process will kick off.
  4. The workflow will send out an email notification to an approver (employee manager in this case).
  5. If approved, the expense data would then be added into the line of business accounting system. The employee would be intimated through email.
  6. If not approved, then the approver would type out a reason and the employee would be notified through an email.

 

Overview of the solution

 

  • Create a reusable Web part which could be configure with the path of a XAP file and would render the XAP file during run time. Call this web part as Generic Silverlight Web Part.
  • Create a new Silverlight Application, name it as ExpenseTemplate.  Create a class library which would contain the data model representing the attributes of the Expense information.  E.g. In this scenario, the classes are shown in the class design below
  • Class diagram of the data model
  • Create a new WSS document library , name it as XapLib. This document library could be re-used for hosting several business forms.
  • Upload the .XAP file to XapLib document library

image 

 

image

 

  • Create a new  WSS page based on the Web Part template page. To this page add an instance of the Generic Silverlight web part.
  • Configure the Generic Web part in design mode of the page with the relative path of the ExpenseTemplate XAP file
  • Configure the Width and Height of the Web Part so as to make the Silverlight application utilize the available real estate without any of it's borders getting clipped.

image

image

  • The final page would appear as follows:

image

  • Create a document library which will be used for submitting the data entered by the user in ExpenseTemplate form
  • In the click event handler of the 'Submit data to server' the Silverlight form will serialize the object model and save the XML data to the configured List.

 

Conclusion

  1. Storing SL apps in a WSS document library offers a very compelling solution towards distributing Silverlight applications. This makes it possible for ordinary programmers to proliferate their organization with SL apps without bothering about physical deployment to the file system of the web servers.
  2. By using WSS/MOSS for building customizable web part pages, we have made it easy for the programmer to rapidly design and deploy data capture forms.
  3. There are still a few questions to be answered:
  4. After submission of the data to the destination Document library, the workflow will process the XML data. How is the XML data processed in the subsequent steps of the workflow?
  5. What sort of UI do we employ for letting the approver view the XML data in a business friendly way?
  6. What mechanism do we employ for validating the business forms during data submission? (e.g. Burn the logic into the SL code or use an external logic processor assembly, etc)
  7. I would be addressing these questions in the Part 2 of this article which I will be posting shortly on this blog.

 

 

 

Disclaimer

The ideas presented in this article are solely those of the author and may not represent Microsoft Corporation.

An approach towards centralized web.config management in WSS/MOSS

Introduction

Let me be very frank with you. I love WSS 30/MOSS technologies. Building a portal for sharing information and collaborating has been made so simple with WSS/MOSS. The architects of WSS/MOSS rightly chose to build over the foundations provided by ASP.NET. Like any ASP.NET application, the web.config file plays a very important role in WSS/MOSS in carrying out low level technical customizations. WSS/MOSS web.config files can be humungous. Try as much I can, I invariably need more than an attempt to get my web.config modifications right. The problem becomes even more significant if I am working on a load balanced SharePoint farm comprising of more than one Web Front End server. The sheer size and complexity of a WSS/MOSS web.config and the likelihood of making inadvertent modification were the key drivers for this post. In this post, I have described an approach to simplify the task of modifying web.config files in a WSS/MOSS farm and keeping all the web.config files in sync in a multi-WFE farm.

Typical web.config file

The web.config file for a MOSS/WSS application has a section group by the name of 'Sharepoint'. This group has several sections defined within. Some of these sections are listed below:

  1. SafeControls
  2. RuntimeFilter
  3. WebPartLimits
  4. WebPartCache
  5. WebPartWorkItem
  6. WebPartControls
  7. SafeMode
  8. MergedActions
  9. PeoplePickerWildcards

Out of the above, I find myself dealing with SafeControls very often. Therefore, I shall restrict my discussion to the centralized management of entries under SafeControls section.

Approaches to Centralized Management of web.config

Based on discussions with my colleagues, I have listed down some of the possible approaches that would help in simplifying the management of web.config files on a more 'central' basis.

  1. Install customizations in the \12\CONFIG directory as specified in the WSS SDK 
  2. Use the SPWebConfigModification class. As implemented in the SharePointDebugger solution.
  3. Do nothing! Manipulate the web.config file directly as a XML file.

Using section handlers for converting configuration XML into custom objects

A section handler in ASP.NET 20 is a custom assembly that is used to handle the contents of a particular section. WSS/MOSS rely on section handlers to provide 'getters' for the web.config, rather than reading the files through XML DOM library. A section is a custom XML hive in the application configuration file for storing application specific information.

  1. All sections are registered under the <configSections> node of the web configuration file
  2. A section must have a class associated with it. This information is provided by the Type attribute
  3. image
  4. The class must implement interface IConfigurationSectionHandler
  5. A typical section would resemble:
  6. image
  7. The interface IConfigurationSectionHandler has a method object Create(object parent, object configContext, XmlNode section); The parameter 'section' represents a XML fragment shown above
  8. The method Create is expected to return a meaningful custom object which would be useful for accessing the XML information. In most cases the implementation of your Create method would end up returning a collection of custom objects.

Making a configuration file read information from a SQL Database

Out of box Section handler for SafeControls section

The SafeControls section has a registered handler which is of the type Microsoft.SharePoint.ApplicationRuntime.SafeControlsConfigurationHandler. This class cannot be inherited because it is marked 'sealed'. As discussed above, the type SafeControlsConfigurationHandler implements the interface System.Configuration.IConfigurationSectionHandler. In the following sections I have described an approach to create a wrapper section handler which would read a list of SafeControls information from a SQL database and pass it on to the Create method of SafeControlsConfigurationHandler, thereby fooling the latter class about the source of the configuration information.

A custom section handler for SafeControls

  1. Let us design a relational table called tblSafeControls. This table would have replicate the attributes found in the <SafeControl> element through relational columns. There would be columns for Assembly, Namespace, Typename, Safe and AllowRemoteDesigner
  2. image
  3. Let us add a connection string information to the <SafeControls> element as shown below
  4. image
  5. Let us create a class MySafeControlsConfigurationHandler and implement the interface IConfigurationSectionHandler.
  6. Provide a body for the method public object Create(object parent, object configContext, XmlNode section);
  7. What next? If you observe, one of the inputs to this method is an object of XmlNode. This is the information contained in the web.config file in XML format.
  8. The pseudo code for the Create( object parent, object configContext, XmlNode section) is
    1. Read the connectionStringName attribute from the 'section' DOM parameter
    2. Obtain the connection string represented by connectionStringName from the <connectionStrings> section
    3. Establish a connection to the database and read the list of  safe controls from the table tblSafeControls.
    4. Create a clone of the XML node 'section', name this 'section_clone'
    5. Manipulate the XML DOM for 'clone_section' by adding new <SafeControl/> elements , thereby populating the in-memory XML DOM with information from the central database. 
    6. In the last step, create an instance of SafeControlsConfigurationHandler class and invoke the Create method by passing the section_clone XML node
    7. The return Object obtained from Create should be returned back to the caller
  9. image 

Conclusion

To deploy the above system , the following one time activities need to be carried out. After this, all additions to the <safecontrols> should happen at the database tables

    1. The web.config for all the WFEs need to be modified by adding the connection string  information.
    2. The custom handler assembly should be added to the GAC on all the WFEs.I am not sure if this has been delved with before.

This approach would require further engineering refinement. E.g. Caching of information to avoid making repeated trips to the central configuration database. I would be delighted to hear your thoughts on this idea, your responses may give me the spark to take this work to a finished solution.

Disclaimer

These ideas expressed here are solely those of the author and not necessarily shared by Microsoft

WSS/MOSS Certifications - I did it

Years ago I used to be skeptical of certifications. My argument with my manager was that you learn stuff doing things hands on and not rote. But, times have changed. MOSS/WSS is a very wide area and getting deep hands on experience in all the departments is hard to come by. In my humble opinion, this is where certifications come in handy. It is a comitted exercise which makes you take a deep look into all nook and crannies of a complicated software.

BTW, I passed the 4 exams - WSS/MOSS app dev & configuration a couple of weeks ago.

Dynamic loading of XAML in Silverlight- Interesting possibilities for Line of Business Applications

Introduction

Large scale Line of Business Applications (such as ERP, CRM, Accounting) require extensive end user customization. This is a natural outcome of the fact that no two business are alike and customizations are inevitable. Consider an Human Resource module of an ERP system. There would be differences in data attributes required for an Employee record from one organization to another.

The challenge lies in building a software framework that allows customization after the core product has been shipped. You do not want to maintain source code versions for each customer you sell your Accounting package to. In the past various ERP vendors have addressed the above problem by using home grown solutions. E.g. One of the largest ERP products stores the meta data of each and every UI widget for every form as distinct records of information in a configuration database. E.g. Width, Height, X, Y, Caption , etc. The user interface of the form is constrcuted on the fly at runtime.  Customizations at the end user level can be carried out by editing the configuration database.

XAML

XAML is a very rich declarative language that rescues the modern day application developer from worrying about how to provide a dynamic UI engine. XAML is a general purpose declarative XML driven system to represent an Object hierarchy. Any object hierarchy of CLR compliant objects could be persisted in XAML syntax into a file or a BLOB in a database. The same object tree can be re-created from the XAML.

Dynamically instantiating objects in an external XAML file

In the sample that accompanies this blog, I have used the following syntax for loading a XAML file from the local disk and injecting the newly created tree into an existing Canvas element. Have reduced the code and XAML for the sake of simplicity.

Sample Xaml

                <Canvas>

                    <Canvas x:Name="xamlcontainer1" Width="300" Height="300"  Canvas.Left="20" Canvas.Top="60" Background="LightGray">
                        <TextBlock TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="msglog"> Region for dnyamically adding XAML</TextBlock>
                    </Canvas>
                </Canvas>

Sample Code

                Object dynaxaml;
                try
                {
                    xamlcontainer1.Children.Clear();  //clear the Canvas of any prior elements . such as the TextBlock
                    dynaxaml = XamlReader.Load(<XAML contents, passed as a string>);  //create the Object graph from the XAML string
                    xamlcontainer1.Children.Add((UIElement)dynaxaml) //inject the Object graph into the Canvas

                }


 

Note the presence of the  <Canvas x:Name='xamlcontainer1' > . The object graph is added to the Children property of the Canvas

Demo Silverlight Application

  1. Extract the contents of the attachments and save them to local disk
  2. The attachment contains sample code and two files DynamicUISample01.xaml and DynamicUISample02.xaml
  3. Select the button to browse for file DynamicUISample01.xaml on the local disk
  4. Click the Clear button to clear the contents of the Canvas where dynamically created objects were inserted.
  5. Repeat the process with DynamicUISample02.xaml

The Road Ahead

We are not done yet. The sample presented here establishes one of the very critical elements of building a class of LOB applications which require customization by the the end user (the IT team of the business owner to be precise). However, a complex application would require interaction with various serivces such as searching for records, displaying search records in a grid, navigating to and fro in the search results, deleting a record and so on. Principles layed down by Composite Application Block for WPF would have to be harnessed to build applications which would work in a plug anf play fashion.

Windows SharePoint Services 3.0 document library as a repository for XAML files!

I see immense potential for leveraging WSS as a repository for dynamic screen definitions. As somebody who has worked with MOSS from the time it was in Beta 1, I find it difficult to rationalize building custom databases for such a purpose. Shall blog about this some other day. Tata for now.

Hosting a Silverlight application on blogs.msdn.com

I did not find any ready documentation to host the Silverlight plugin on blog post on this site. So I set to out try this out my self.

 

 

 

I spent an hour dabbling with editing the HTML code and trying to upload a XAP file into pictures library. All of that failed! Thankfully there is a much easier way to host a Silverlight 1.0/2.0 plugin. The steps are as follows:

  1. Install Windows Live Writer from here.
  2. Download the Silverlight plug-in from here. This plugin will allow you to embed a SL app in your blog.
  3. Sign up here to create an account that would give you storage space and let you host your exotic SL apps. Remember the Account ID and the Key.
  4. Follow the instructions to upload your XAP file to the above site. You will be guided to create a manifest and you can then view your application in a test page from within the site.
  5. Execute Live Writer and connect to your blog
  6. Once, inside this application, you can chose to create a new blog entry
  7. Drag and drop the 'Insert Silverlight Streaming' plug-in into your blog page
  8. image
  9. You will be prompted for the Account ID and the Key in the dialog shown above.
  10. Click Refresh button and you should be able to see your Silverlight application that you had uploaded earlier
  11. Select the application and you are almost done!
  12. Save and publish your blog.
Composite Web Pages using Silverlight, Webparts and SharePoint

I am an ardent admirer of Composite Application Block(CAB) and it's WPF avataar Prism. Those of you have worked with these technologies will agree with me that these blocks are a wonderful way to make customizable applicaitons composed out of modular UI applets.

The desing of CAB & Prism framework allow for UI screens to be composed out of parts that were 'manufactured' in different development groups. The framework allows loosely coupled event based communication and data sharing to take placed between the UI parts. At a more fundamental level this is achieved through a centralized event publish-subscribe architecture. Isn't that an awesome architecture for building complex Line of Business applications!

Wait a minute! Before I get too enthusiastic I am mulling if there is any existing infrastructure that I can leverage. I do have a wish list which is neither fulfilled by CAB nor WPF. I want

  1. The UI should be composed in a page loaded in Internet Explorer or any other browser.
  2. Have an eventing model that should be completely client side and no going back to the server very frequently.
  3. Reduce deployment and administrative efforts  
  4. Implement a menu based page navigation system and implement role based security for the pages

CAB and Prism do not operate in the context of a browser. Neither do I want to incur the cost of creating an applicaiton from the ground up. So, what do we do?  I have an idea and please hear me out before you ask me to leave the class.

Create UI parts using SIlverlight and host them as web parts in SharePoint web pages. Use Javascript for connecting events between two Silverlight webpart.

Why Silverlight? You can create Rich Internet Applications using managed code and a degree of browser and OS independence unlike anything seen before. SL 2.0 offers rich support for invoking web services. AJAX too has support for web services but complexity in interoperability can be quite daunting.
 

Why Web parts? You can construct complex modular web pages by dragging and dropping web parts from a central catalogue. ASP.NET 2.0 provides the ground work for the persistence and personalization web parts. ASP.NET 2.0 web parts can be 'connected' but this requires a post back to occur.
 

Why Sharepoint? Built on ASP.NET 2.0. You get a complete web part catalogue, persistence and personalization services built in. Both WSS 3.0 and MOSS 2007 (which is built on WSS ) are very widely adopted platform for portals.

Why Javascript? This was not apparent to me at first. I thought that there should be an easy way for SL apps on the same page to communicate amongst themselves. Alas! I was politely reminded that each Silverligth application run in it's own app doman and cannot share variables with another app domain. Hence Javascript is the best way to route events from the publisher web part to the subscriber web part.

Probable Scenarios

  1. Display Employee details in and LOB application: A web part to display Employee Details and another web part to do a Search on Employee. Connect the two web parts through an eventing mechanism so that when an employee record is searched through the Search on Employee web part, the Employee Details web part is notified (without a post back) and details fetched on the fly through web services.
  2. Customer call center application: A page constructed with the following Silverlight web parts. A web part to Search for a Customer, a web part to display Customer Transaction History details, a web part for entering Customer Complaints, a web part for displaying past Customer Complaints. Each of these web parts would function independently. However, they would respond to events from the Search for a Customer web part and update themselves autonomously. The flow of activities is as follows:
    • Customer service agent browses to http://company/CRM/CustomerIssues.aspx
    • User searches for a customer using firstname/lastname/identification number using the Customer Search Web part
    • The search result(s) are displayed in a scrollable list within this web part.
    • User selects a customer from the list
    • The selection event notification is broadcasted to all other web parts (Customer Complaints & Customer Orders)
    • The event arguments consists of the customer ID.
    • The Customer Complaints web part fetches the required informaiton for this customer using a web service
    • The Customer Order transactions web part fetches the required information for this customer using a web service
    • The Silverlight web parts Customer Order and Customer Complaints render their information
    • Agent takes subsequent actions.
  3.  

Steps ahead

I would like to hear your comments on the above idea. I would also be exploring within Microsoft if there are any teams working on this idea and think more on the Javascript/Silverlight event broker plumbing model.

 

Long running operations using BackGroundWorker class
As a consultant, I encounter several customer queries with regards to application architecture. This was a query from a customer on how to handle long running operations in a windows forms 2.0 application. I recommended the class BackGroundWorker as one of the approaches. Here is a short and a really quick start with BackGroundWorker class built around the MSDN sample code snippet.
 
Why do we need to handle long running tasks in a special way?
Consider a form which has a button. Clicking on the button should invoke a method in the Form class. As an example,assume that this method is named ComputeFibonacci. In a non-asynchronous approach, the the windows forms would enter a suspended state the moment the button is clicked. This is because, the windows message loop which runs on a per thread basis is not able to process the queued up UI events like mouse move, click, etc. Thus, the application would become non-responsive and the user would have no way to even quit the applicatoin. The only way out for the end user, is to use the Task Manager to kill the process.
 
How can a long running method be made to execute in a separate thread?
Use the services of BackgroundWorker class.
 
What is the BackgroundWorker class?
This is a helper class allows you to run a time consuming process on a separate thread. It is the ability of running a long operation on a separate thread that makes BackgroundWorker class powerful.
 
How should the BackgroundWorker class be initialized?
  1. In a typical Win forms application, the form will have a member variable of type BackgroundWorker.
  2. As an example assume that this instance is named backgroundWorker1
  3. Create a event handler in the form class for the DoWork event. Assume that this event handler is backgroundWorker1_DoWork.
  4. Invoke the method RunWorkerAsync.
  5. The object backgroundWorker1 will immediately invoke the delegate backgroundWorker1_DoWork. Note- this invocation is on a thread that is separate from that of the main form. This can be verified by comparing the thread identifiers.
  6. In this method, kickstart the long operation, by making a simple method call to ComputeFibonacci.
Updating the UI progress in the midst of the ComputeFibonacci?
Remember that calls to method ComputeFibonacci has occurrred on a separate thread. The controls of the parent window should not be accessed directly from within ComputeFibonacci. The method ComputerFibonacci may like to update the status bar as and when an iteration is complete. To achieve this the ReportProgress delegate of backgroundWorker1 should be invoked at appropriate times.
 
The event handler for ProgressChangedEvent which has been defined in the body of the main form will be invoked at regular interations in ComputeFibonacci and this invocation will occur in the same thread as that of the main Form.
 
How does the UI know when the long running operation is over?
When the required number of interations is over in ComputeFibonacci, the delegate RunWorkerCompleted of the backgrounWorker1 object should be fired from within this method. The main form should handle the event RunWorkerCompleted appropriately and update the UI.
 
How to terminate a long running operation?
Since, the UI is free to handle events, if the user clicks on the Cancel Async button, the method CancelAsync of the object bakcgroundWorker1 is invoked from the click handler. This kills the background thread that was doing the long running operation.
 
Running the sample code.
The sample code comprises of a single C# Windows Application project. Extract the contents to a folder. Compile and run the app. Enter a number ( eg: 35) in the up-down control and click the button Start Async. Observe the progress bar. Enter a larger number (Eg: 50) and try to stop the long running operation by clicking on Cancel Async button.
Installing Enterprise Library 2.0 for .NET Framework January 2006 without Visual Studio 2005

Hi all,

I have the habit of having the online documentation of all the Microsoft products readily accessible. I was trying to install Enterprise library 2.0 on my laptop to for the same purpose. I do not have VS.NET 2005 on my laptop. I use a Virtual PC disk to do my development activities. However, I wanted to have quick access to the Enterprise Library documentation on my laptop, without having to turn on my virtual machine. I realized the hard way that installing Enterprise Library without VS.NET 2005 does not bring up the documentation. However, I was lucky to find  a way out.

This is what I did:

  1. Ensure that MSDN for Visual Studio 2005 is installed. This will ensure that dexplore.exe is available.
  2. Install Enterprise Library 2.0
  3. The shortcut key for launching Enterprise Documentation will be available at:
  4. Start --> All Programs --> Microsoft Patterns & Practices --> Enterprise Library 2006 --> Enterprise Library Documentation.
  5. Clicking on this shortcut will open up dexplore.exe but it may not show you the Ent Lib documentation.
  6. Bring up the properties of the above mentioned Ent Lib documentation shortcut by using the context menu.
  7. Replace the contents of the text box "Target" with the following:
  8. "%CommonProgramFiles%\Microsoft Shared\Help 8\dexplore.exe" /helpcol ms-help://ms.EntLib.2006Jan
  9. (keep a copy of the original text just in case, you need to revert back)
  10. Press Ok and try now. Dexplore.exe should be able to show the help collection of enterprise library.

Hope this helps!  

 

 

Invoking SqlMembershipProvider from a Windows forms application

 The abstraction provided by MembershipProvider base class is a very powerful concept in ASP.NET 2.0. It simplifies the management of user information by providing a neat layer.

ASP.NET 2.0 provides the SqlMembershipProvider class and the aspnet_regsql command line utility to create the database user management database. My customer was building a hybrid application, which was mainly ASP.NET 2.0, but there were a few forms implemented using Windows forms. The question  arose as to how a windows forms login form can be created that will use the SqlMembershipProvider.

This is what I did.

  • Created a new windows forms application. Add an app.config file.
  • Added the following section to the config file.
  • Ensure that the settings match with your database (which would have been created using aspnet_regsql.exe tool)

  <configSections>
    <section name="connectionStrings" type="System.Configuration.ConnectionStringsSection, System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" requirePermission="false" />
  </configSections>

  <connectionStrings>
    <add name="mydb" connectionString ="Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Helloworld;"/>   
  </connectionStrings>

  • Wrote a factory method to instantiate and correctly initialize the provider. ASP.NET 2.0 reuses a single instance of the provider for servicing all requests.

    class MembershipProviderFactory
    {
       static public MembershipProvider Create()
        {
            string cn="";
            System.Configuration.Configuration config=
            ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            if (config == null ) throw new ConfigurationErrorsException ("Could not read config file");

            //searching for the connection string element with the zero th index.
            ConnectionStringsSection cnstringssection;
            cnstringssection = config.ConnectionStrings;
            if (cnstringssection.ConnectionStrings.Count == 0) throw new ConfigurationErrorsException("connection string information not found in config file");

            ConnectionStringSettings cnsettings;
            cnsettings = cnstringssection.ConnectionStrings[0];
            cn = cnsettings.ConnectionString;
 
            if (string.IsNullOrEmpty (cn))
            {
                throw new ConfigurationErrorsException("connection string information (cn) not found in config file");
            }

            SqlMembershipProvider prov = new SqlMembershipProvider();
            NameValueCollection vals=new NameValueCollection ();
            vals.Add("name", "sql");
            vals.Add("connectionStringName", "mydb");
            vals.Add("applicationName", "MyApplication");
            vals.Add("maxInvalidPasswordAttempts", "100");
            prov.Initialize("sql", vals);
            return (MembershipProvider)prov;
        }
}

  • The applicationName property should match the web.config settings in the ASP.NET application.
  • The code for validating the user credentials is as follows

            System.Web.Security.MembershipProvider    memprov;
            memprov = MembershipProviderFactory.Create();
            if (memprov.ValidateUser("user1", "pass@word1") == false )
            {
                MessageBox.Show("Invalid username or password");
            }
            else
            {
                MessageBox.Show("User credentials verified");
            }

  • ..The important thing to be remembered here is that SqlMembershipProvider expects the <connectionStrings> section in the configuratin file for connecting to Sql server. I would be very glad if somebody can find out how SqlMembershipProvider can be initialized without the need for <connectionStrings> section in the app.config file.

I do believe that this is not the best way to solve my customer's problem. A better way would be to expose web services for the required functionality and let the windows forms app connect to this service using WSe 3.0/WCF and passing the user name token along with the method invocation. This would be more secure because the connection string is not exposed to the caller and it would be n-tiered as well.

 

My first blog entry

I am excited!

Page view tracker