Sunday, May 30, 2010

Using WSP Builder for creating and deploying a Solution

The WSP Builder is an excellent tool for creating Solution package automatically, and I am using this for a long time, so thought to write about it.

This tool is created by Carsten Keutmann and can be installed on bot VS2005 and VS2008. First you have to download from the codeplex then install.

Earlier, we had to create a "CAB Project" from the "Setup and Deployment" section on the Visual Studio. Then add the other project as resources to this CAB Project, Build the project and rename the output file extension to WSP, looks like lots of steps and efforts!!! WSP Builder is a single step creation.

Only thing need to to is Right Click on the Project of the Solution Explorer, WSPBuilder -> Build WSP

This step will generate the log that shows the components added in the WSP file created.



Important: Please verify very closely the output logs generated and check all the required DLLs are added in the WSP or not.

Once you have successfully built the WSP, now its time to deply it using STSADM commands. For this you have to navigate to the \12\BIN\ directory.

1st Command: AddSolution

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\BIN>STSADM.EXE -o addsolution -filename "E:\Project Server\Server Data\GenerateFormReceiver\EventReceiverBinder\EventReceiverBinder.wsp"
 

2nd Command: DeploySolution

STSADM.EXE -o deploysolution -name EventReceiverBinder.wsp -immediate -allowGacDeployment -url http://somu/pwa



Gotcha: The above command will give you an error "This solution contains no resources scoped for a Web application and cannot be deployed to a particular Web application."
At this point you might think there is problem in the Features.xml file, where you are trying to re-defining the scope property.

But the trick is, the DeploySolution cammand should not use a deployment scope, means the "url" switch at time moment. Therefore the solution will be globally deployed.

STSADM.EXE -o deploysolution -name EventReceiverBinder.wsp -immediate -allowGacDeployment

voilla!!! you successed.

3rd Command: ActivateFeature

STSADM.EXE -o activatefeature -name EventReceiverBinder -url http://Somu/PWA -force

And you are done.

Uninstalltion script:

Deactivate The feature:

STSADM.EXE -o deactivatefeature -name EventReceiverBinder -url http://Somu/PWA -force

Retracting the Solution:

STSADM.EXE -o retractsolution -name EventReceiverBinder.wsp -immediate

(Wait for couple of seconds...)

Deleting the Solution:

STSADM.EXE -o deletesolution -name EventReceiverBinder.wsp

 if you have not wait for the period, might encounter the following error.

The solution "EventReceiverBinder.wsp" has been deployed in the farm. Please retract the deployment before removing the solution.You can also use the -override parameter to forcibly remove the solution, but you will not be able to retract the solution deployment.

Saturday, May 22, 2010

Updating Date and Integer type fileds in InfoPath programmatically

From the title of the topic seems that this task should be easy! But to my own surprise I find it very difficult and time consuming activity.

The Task:
We are having a InfoPath form Template, that is already published in a SharePoint Form Library. Now, We have to create the InfoPath form dynamically and submit the form in the SharePoint library. This process was described earlier in this post.



Now, the problem is the InfoPath form contains certain Date and Integer data types. And I have a C# application to do the task.

First Problem:
If I have to do this task inside InfoPath managed codes using VSTA (Visual Studio Tools for Application), the following piece of can be used:

XPathNavigator root = MainDataSource.CreateNavigator();
XPathNavigator nameNode = root.SelectSingleNode("/my:myFields/my:Name", NameSpaceManager);
nameNode.SetValue("newvalue");

But, I am not using VSTA and have to navigate the XML node programmatically. The "NameSpaceManager" only available inside InfoPath managed codes only. Therefore the "NameSpaceManager should create first in the code:

public XmlNamespaceManager InitNamespaceManager(XmlDocument xmlDOMDoc)
{

XmlNamespaceManager xnmMan;
xnmMan = new XmlNamespaceManager(xmlDOMDoc.NameTable);

foreach (XmlAttribute nsAttr in xmlDOMDoc.DocumentElement.Attributes)
{
     if (nsAttr.Prefix=="xmlns")
         xnmMan.AddNamespace(nsAttr.LocalName,nsAttr.Value);
}
return xnmMan;
}

XmlNamespaceManager NamespaceManager = InitNamespaceManager(XMLDoc);


This NameSpaceManager is required to resolve any NameSpace related issues at the time of creating XPathNavigation.


Second Problem:

This problem raised when I updated the Date and Integer fields of the InfoPath file in my code. After submission of the file, when I try to open, the following error message displayed:


After googled some time, I learnt that, XML only understand a single date format. That is "yyyy-MM-dd". You have to pass the dates in this format only. So, I used:

newNode.SetValue(XmlConvert.ToString(DateTime.Now, "yyyy-MM-dd"));

Third Problem:

After putting that dates in the correct format, I was a bit confident that the problem has been resolved. But the previous error message was again shown me, i.e. "Schema validation error".

Fortunately, I got this and this on the Internet, and fixed the entire problem finally.

XmlNamespaceManager NameSpaceManager = InitNamespaceManager(XMLDoc);

XPathNavigator nav = xd.CreateNavigator();

//For a text field value
nav.SelectSingleNode("/my:myFields/my:Requestor", NameSpaceManager).SetValue("SampleData");

//For a date Field
XPathNavigator navTRDDate = nav.SelectSingleNode("/my:myFields/my:TRDDate", NameSpaceManager);

if (navTRDDate.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance"))
   navTRDDate.DeleteSelf();

navTRDDate.SetValue(DateTime.Now.ToString("yyyy-MM-dd"));

Wednesday, May 19, 2010

Generating Public Key Token in Visual Studio

The "Public Key Token" is the unique identifier for a DLL that is deployed in GAC (Global Assembly Cache). This is particularly important for me, as I need to specify that in Features.xml file for SharePoint development.


Now, getting the Public key Token is not that simple. Either you have to drag the DLL to assembly, then only you will find the Public Key Token along with the other information like Assembly Name, Version etc.


Following are the steps for generating the Public Key Token right inside the Visual Studio 2005/2008 (This screen shots are from VS 2008)


First, you need the create your Project or the Class Library, write the required coding, then sign the assembly with a key.


Secondly follow these steps, this is one time effort and can be used for n number of projects.





On the following screen you need to pass the following information
Title: A convenient title to remember
Command: C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\sn.exe
Arguments: -Tp $(TargetPath)
(note: the argument field is case sensitive)







Tuesday, May 18, 2010

Consuming a web service in a Windows Application

As the topic looks very simple, but I had wasted a couple of hours of development time in a project recently. Therefore, I thought to blog it right away.

The following steps need to be done using Visual Studio 2008:

This is the most important step. The web service address should not paste directly on the "Address" bar. You need to first click on the "Advance" button, then only the web service URL should be entered. This way you will get all the methods exposed by the consumed web service.





Sunday, May 2, 2010

Get User Details without writing any code in a InfoPath Form

Hi All,

In recent work I need to show the currently logged in user in a InfoPath form. At first I thought of writing some codes, but later I encounter this post claytoncobb to figure out a complete no code solution.

Here, I am going to use the SharePoint web service UserProfileService (http://ServerName/_vti_bin/UserProfileService.asmx). The design of my form look like this:

Now, For creating the data connection, following steps need to perform:
  1. With InfoPath opened go to Tools > Data Connections, and click 'add...' to add a new data connection to the form. This opens up the Data Connection Wizard.
  2. We want to receive data from the WS about the current user, so choose receive data' and click next.
  3. Our data source is a WS so choose 'Web Service' and next.
  4. Now you will have to point the wizard to the WS. Type an address similar to this: http://ServerName/_vti_bin/UserProfileService.asmx  and click next.
  5. Here you get a list of all methods for that WS, choose GetUserProfileByName and click next.
  6. In this screen you can specify what parameters are sent to the method, we are relying on the method's ability to return the current user name if no value is passed to it, so we will leave this as is (no value is passed to the method) and click next.
  7. Click next and make sure 'Automatically retrieve data when form is opened' is checked.
  8. Finish the wizard.
The GetProfileByName method returns a PropertyData array. You can think of it as a repeating table of name and value pairs.
So Now that you have a data connection that can get the current users, you can use it values. In this example I will show the user's first name in a TextBox.

  1. Add a textbox to the form.
  2. Go to the first textbox's properties (double click it).
  3. In the 'Default Value' part, click the 'fx' button next to the 'Value' field. this opens up the formula builder dialog.



  4. Click 'Insert field or group'.

  5. In the data sources drop down, choose the GetUserProfileByName data source.
  6. Expand all groups under the 'dataFields' group, and choose the 'value' field. Don't click OK yet!


     
  7. With data 'value' field selected, click the 'Filter Data...' button and 'Add...'.
  8. In the first drop down (value) select 'Select a field or group...' and choose the 'Name' field under the 'PropertyData' group.

  9. Leave the middle drop down as is ('is equal to') and in the last drop down choose 'type a text...'.

     
  10. This is the part where you specify which property to put in the textbox. As we said the method returns multiple properties about the user. For this textbox we want to put the user's first name in, so type 'FirstName' (this is case sensitive!). I have included the property list you can use here (just below), so if you want some other property, just type its name instead.
  11. That's it, all we have to do is to confirm everything so Click 'OK' for every open dialog box until you are back in the design mode.
  12. click 'Preview' and see the wonder!
  13. If you want more details repeat steps 1-11 and enter different property names in step 10.
Gotcha:
After completing the above steps you might not able to see your data as expected. This means the form might show an empty field and you will be thinking where is the problem.

As we are accessing the user information form the profile object, all the values (like first name, last name etc) of a user should be defined there. From a SharePoint site you can click on a user link to see the detail information in UserDisp.aspx page.
 

Finally, here is the complete list of default profile properties get returned by the userprofileservice. I think they are pretty self explained:
UserProfile_GUID
AccountName
FirstName
LastName
PreferredName
WorkPhone
Office
Department
Title
Manager
AboutMe
PersonalSpace
PictureURL
UserName
QuickLinks
WebSite
PublicSiteRedirect
SPS-Dotted-line
SPS-Peers
SPS-Responsibility
SPS-Skills
SPS-PastProjects
SPS-Interests
SPS-School
SPS-SipAddress
SPS-Birthday
SPS-MySiteUpgrade
SPS-DontSuggestList
SPS-ProxyAddresses
SPS-HireDate
SPS-LastColleagueAdded
SPS-OWAUrl
SPS-ResourceAccountName
SPS-MasterAccountName
Assistant
WorkEmail
CellPhone
Fax
HomePhone