Friday, November 27, 2009

Using configurations in MOSS Web Parts/ InfoPath browser forms

There are times when we want some values to be configurable. For example, a hyperlink in MOSS web part or an InfoPath browser form must be configurable so that when the artifacts are moved across environments, the link points to correct target.

This can be achieved in simple web.config changes of MOSS web application as follows:
Step 1:
Define a sectiongroup tag under

<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
</sectionGroup>

Step 2:
Add a corresponding .Settings tag under applicationSettings group we defined

<section name="SampleConfig.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />


Step 3:

Now that we have defined a placeholder, we can define actual configuration settings under it.
<applicationSettings>
<SampleConfig.Properties.Settings>

<setting name="AHyperLink" serializeAs="String">
<value>http://abc</value>
</setting>
</
SampleConfig.Properties.Settings>
</applicationSettings>

Why this works?
Thanks to the ASP.NET infrastructure upon which MOSS is built. The MOSS web application undergoes the same ASP.NET request processing pipeline. Hence, the configurations defined above work. Please note that the highlighted tag names must match for this to work.

Tuesday, November 10, 2009

Remote Debugging in Visual Studio

Overview:
Remote debugger is a tool provided by Visual Studio to debug an application hosted on a different machine.
In local debugging, it is required to have application hosted on the development machine. We attach a debugger to the local process (e.g. W3WP.exe) which hosts the application. The symbol files (.PDB files) location is present on the same machine.
In remote debugging, the application can be hosted on a different machine (or server). Yet, we can debug it as if it is on the local machine.



Key Scenarios where remote debugging is must:
1. Debugging of ASP.NET web applications/Web services right on the server
2. Debugging InfoPath browser forms
3. Debugging of Web Parts deployed on MOSS



Installing Remote Debugger on the server:
Remote debugger setup can be found at ”Program Files\Microsoft Visual Studio 8\Common7\IDE\Remote Debugger” in Visual Studio Setup.
If it is not possible to install the setup on the server, copy and paste following directory to the server:
(Program Files\Microsoft Visual Studio 8\Common7\IDE\Remote Debugger\ x86 (or x64if server is 64 bit) to any location.



In this post, I will explain first scenario:
Remote debugging of ASP.NET web applications/Web services



To remote debug ASP.NET application following setup is required on server and development machine:

Setup on the Server:
Start the remote debugger by double clicking msvsmon.exe located in the Remote Debugger folder.
If you are debugging ASP.NET application, in command prompt type IISAPP.VBS. This will list all the worker processes and their PIDs. Note the Process ID of the worker process to be debugged.
Note: If you are debugging InfoPath form or a MOSS web part, please note the PID of the MOSS web application.



Setup on the development machine:
1. Go to debug -> attach to Process
2. Enter the machine name on which msvsmon.exe is running
3. Select the w3wp.exe with correct PID
4. Click attach



Debugging will start and break points will be hit.


Common Problems in Remote Debugging:
1. Debug Symbols not getting loaded
Solution:


Many times source code gets updated after the build was deployed on the server. Rebuild the source code and redeploy the ASP.NET application.
If this does not help, then
Go to debug -> Modules. This lists all modules.
Right click the module for which symbols are not loaded -> Load symbols

Saturday, June 14, 2008

Harnessing Post-Build-Events in Visual Studio

In class library development, we need to add an assembly to GAC. One way is to open Visual Studio command prompt. And type the command for gacutil /i "DLL" or gacutil /u "DLL".
The disadvantage of the approach is that after every successful build we have to do it manually uninstall the prev version and install the correct version.

In my todays post, we will harness Visual Studio Post-Buil Events to automate this process.

On every successful build the DLL will be automatically added to the GAC.

To begin with,
1. Open any existing class library project to be deployed to the GAC.
2. Right click on the project, add new item-> Text File. Rename the file as PostBuildActions.bat
3. Paste the following content:

@ECHO OFF
SET DEPLOY=%3
ECHO DEPLOY: %DEPLOY%
:: Extract the deploye variable value from the command line
SET DEPLOYVALUE=DEPLOY
ECHO DEPLOYVALUE: %DEPLOYVALUE%

IF NOT %DEPLOY%==%DEPLOYVALUE% (ECHO Skipping deployment & GOTO QUIT)
SET TARGETDIR=%1
:: Fix the extra slashes the the path
echo %TARGETDIR:~0,-2%
:: Fix the extra slashes the the path
SET TARGETDIR=%TARGETDIR:~1,-2%
ECHO TARGETDIR: %TARGETDIR%
SET TARGETNAME=%2
:: Fix the extra slashes the the path
SET TARGETNAME=%TARGETNAME:~1,-1%
ECHO TARGETNAME: %TARGETNAME%
IF EXIST "%programfiles%\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" (SET GACUTIL="%programfiles%\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" & GOTO DEPLOY)
IF EXIST "%programfiles% (x86)\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe" (SET GACUTIL="%programfiles%\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe") ELSE (ECHO Gacutil.exe could not be found! & GOTO QUIT)

:DEPLOY
ECHO.
ECHO Adding assemblies to the GAC...
ECHO.
ECHO.
%GACUTIL% -uf %TARGETNAME%
ECHO.
ECHO.
%GACUTIL% -if "%TARGETDIR%\%TARGETNAME%.dll"
ECHO.
:QUIT
ECHO.
ECHO Assembly added to GAC
ECHO.

4. Right click on solution-> Go to properties -> Build Events -> Post-build events command line and
Paste the following
call "$(ProjectDir)\PostBuildActions.bat" "$(TargetDir)" "$(TargetName)" DEPLOY

(Replace DEPLOY with NODEPLOY to skip adding to GAC)

Monday, June 2, 2008

Multi-Tenant Architecture in SharePoint 2007

What is Multi-Tenant Architecture (MTA)?

MTA is similar to database views where same data is given different representations. As an example, consider a company portal. When an employee logs in, he will be interested more in company happening. On the other hand, when HR person logs in he will be keen to see new buddy referral or other relevant content. MTA implementation provides such dynamism with single portal.

MTA implementation options in SharePoint 2007:

Audience:

Audience is group of users for which the content can be target. SharePoint 2007 audience can consist of Active Directory users or other compatible domain users. We can target list, web part, and navigation for audience. Problem with Audience: Although provide customized content on the fly, Audience cannot be used with master pages.
So if the requirement is to provide different master pages depending on users it is not possible. In our example, if we want to provide a different look-and-feel for HR and employee then it would not be possible.

Solution:

Our problem can be reframed as switching master pages at run-time on the fly. SharePoint 2007 is built on top of ASP.NET 2.0 framework. Thus, we can harness the ASP.NETHTTP request pipeline and change the master page on the PreInit event of Page. For this, we need to create HTTP module and change the master page on the fly by reading page path from web.config.

Steps:

1. Define a class that implements IHttpModule

2. In the PreRequestHandlerExecute method provide a handler for page_PreInit

3. Set page.MasterPageFile property. This can be read from config. It could be similar to /_catalogs/masterpage/BlackBand.master

4. Add the Module to GAC

5. Add the entry to safe-controls section of web.config

6. Add entry to the httpModules section of web.config

That’s it. We are done with MTA implementation.

In my next post, I will provide a walkthrough of creating the MTA module with Visual Studio .NET 2005.

Sunday, December 9, 2007

Saturday, December 8, 2007

Understanding Value of Data Value Objects

One of the critical success factors of any distributed application architecture is the decision about whether to invoke a method on remote object or to communicate with remote object using services.

This decision is highly influenced by the goal of interoperability. The technologies that allow to invoke a method on an object that is residing on a different physical machine across several layers, are usually restrictive in terms of interoperability. That is the method can be invoked by a technology specific mechanism or the output is consumable only by objects in a particular technology.

Solution to this problem is using web services.
Although, web services solve the problem of interoperability, it introduces a new problem of fine grained interfaces.

To understand the problem of fine grained interfaces, consider the following scenario:



The above diagram shows the interaction between a aspx page i.e. client and the services in order to build a UI for customer and order details.

As shown in the above diagram, in order to gather all required details to build a UI for customer and his order details, the client calls GetCustomerName(), GetOrderDetails() and GetProductDetails() methods of Customer, Order and Product Service respectively.


Hence, the client must be aware about the fine-grained details of which method of the service to invoke over the network. In other words, in this pattern, the remote objects expose a fine grained interface.




Disadvantage of fine grained interface:
In order to build a single UI, three calls to service over the network are required even in this highly simplified example. In the real world scenario, a large number of calls to service over the network will be required resulting in severe performance hit.

Solution:
Coarse grained interfaces:
When the interfaces exposed by remote objects are coarse grained, the client will deal with high-level methods like GetCustomerOrderDetails(). The method will return all the required data in single service call.

Data Value Objects (DVO):
DVO design pattern applies the concept of coarse grained interfaces.
In this pattern, the client will invoke a single service method like, GetCustomerOrderDetails(). This method will return a single DVO with all the required details.













As shown in the above diagram, a single call to GetCustomerOrderDetails() assembler service returns a DVO with all the data required for UI.

Implementing DVO:
There are many approaches to implementing DVO. Following are some of the approaches:
1. Implementing a class with attributes for DVO.


In this approach, the DVO class typically contains all the required attributes with Get, Set properties.
For example,
public class Customer
{
public string Name
{
get { return this.Name; }
set { this.Name = value; }
}
}


Advantage:
Less marshalling overhead because simple attributes


Disadvantage:
The approach requires a new class to be created for each DVO. Typically all the distributed applications requires a large number of DVO. It results in large number of classes. Thus, maintaining the attribute based DVO becomes difficult

2. Implementing a class with a generic DVO with wrapper over a simple Dataset

In this approach, class with DVO as a wrapper over a dataset is developed. The attributes of the class with still have the get, set properties. But the properties will be mapped to dataset.

For example,

public class Customer
{
public string Name
{
get { return this.customerDataSet.Rows[0][“Name”].Value; }
set { this.customerDataSet.Rows[0][“Name”] = value; }
}
}

Advantage:
i. Ease of maintenance because of dataset

No extra classes are required. For example, the Customer, Order and Product details can be added as tables to the dataset with all the required relationships
ii. Leveraging the high performance XML serialization capabilities of .NET 2.0 DataSet, reduces the marshalling overhead significantly

iii. Ease of maintenance because of dataset wrapper

The wrapper abstracts the fine grained details about the underlying data. Hence, future changes to underlying data will require changes only to the typed data set. No changes will be required to method of accessing the data as it is abstracted by a property.

Disadvantage:
Lack of type safety. An attempt to create a customer object from order table details will result in run-time error

3. Implementing a class with a generic DVO with wrapper over a Typed Dataset This approach is very similar to above approach. In this approach, class with DVO as a wrapper over a typed dataset is developed. The attributes of the class with still have the get, set properties. But the properties will be mapped to typed dataset.

For example,

public class Customer
{
public string Name
{
get { return this.customerDataSet.CustomerName; }
set { this.customerDataSet.CustomerName = value; }
}
}

Advantage:
i. Ease of maintenance because of dataset. No extra classes are required. For example, the Customer, Order and Product details can be added as tables to the dataset with all the required relationships
ii. Type Safety
An attempt to create a customer object from order table details will result in compile-time error and not run-time error.
iii. Leveraging the high performance XML serialization capabilities of .NET 2.0 DataSet, reduces the marshalling overhead significantly
iv. Ease of maintenance because of dataset wrapper
The wrapper abstracts the fine grained details about the underlying data. Hence, future changes to underlying data will require changes only to the typed data set. No changes will be required to method of accessing the data as it is abstracted by a property.


3. Passing dataset itself as DVO. In this approach, a dataset with required data is passed as DVO. The data is accessed directly from dataset.

For example,
The data will be accessed directly from dataset as
this.customerDataSet.Rows[0][“Name”].Value
Advantage:
Leveraging the high performance XML serialization capabilities of .NET 2.0 DataSet, reduces the marshalling overhead significantly
Disadvantage:
Any changes to underlying data will require changes to all tiers trying to access the data.

Summary:
In distributed applications, the DVO pattern offers a significant advantage. Of the several approaches to implement DVO, typically DVO as wrapper over a typed dataset is the most suitable option.

Wednesday, December 5, 2007

Extension Methods in C# 3.0

Extension method is new language element added to C# 3.0

Extension methods allow developers to extend the existing CLR types with methods of their own.
Without extension methods the same goal can be achieved by sub-classing the original type and adding the required method to the subclass.
However, with this approach we can invoke the newly added method only on subclass, and not on base class. But extension methods make it possible to add new method to a CLR type without having to sub-class the CLR type.

To understand how exactly the extension method works, we will develop a small code snippet to validate a US Zip Code.

To validate a zip code in C# 2.0, following is one of the possible approach:

class Validator
{
public static bool IsValidZip(String USZipCode)
{
return Regex.IsMatch(USZipCode,@"^(\d{5}-\d{4}\d{5}\d{9})$^([a-zA-Z]\d[a-zA-Z] \d[a-zA-Z]\d)$");
}
}

To use this validation logic, the caller code could be

string zip = "12345";
if(Validator.IsValidZip(zip) == true)
{
//Actions
}


Now, we will implement the same functionality using extension method.
We will create an extension method named IsValidUSZipCode.


public static class Validations

{
//Extension method

public static bool IsValidUSZipCode(this string USZipCode)
{
return System.Text.RegularExpressions.Regex.IsMatch(USZipCode,@"^(\d{5}-\d{4}\d{5}\d{9})$^([a-zA-Z]\d[a-zA-Z] \d[a-zA-Z]\d)$");
}
}

Please note the “this” keyword in parameter. It instructs the compiler to treat the method IsValidUSZipCode as extension method.

So far the code is very similar to C# 2.0 implementation.
The major difference is in the code for utilizing this extension method.

The extension methods are accessed directly from the CLR type.
So in this case, the method IsValidUSZipCode can be accessed right from String type.

To use extension method we just defined, we will simply add a using statement as follows:

using Validations;

Now, to validate zip code, add following code:

string zip = "12345";
if(zip.IsValidZip() == true)
{
//Actions
}

Note that we are invoking the extension method directly on the string type variable.

This is how C# 3.0 extension methods can be defined and used.