Monday, December 17, 2007

How to get role items in a K2 blackpearl role

In my last project , I got so many obstacles in development phase. One of most annoying thing I encountered is how to get role item in a K2 blackpearl role. After days of training with K2 guys from Singapore, finally I got the code. Here they are.

First, add this reference to the project you want to place the code.

using SourceCode.Security.UserRoleManager.Management;

Second, declare an instance of UserRoleManager like this :

private SourceCode.Security.UserRoleManager.Management.UserRoleManager _roleManager = new SourceCode.Security.UserRoleManager.Management.UserRoleManager();

Third, add a property like this (note that the connection string may vary according to your computer configuration)


public SourceCode.Security.UserRoleManager.Management.UserRoleManager RoleManager
{
get
{
string connString = string.Empty;

if (_roleManager == null)
_roleManager = new UserRoleManager();

_roleManager.CreateConnection();

if (!_roleManager.Connection.IsConnected)
{
connString = "Integrated=True;IsPrimaryLogin=True;Authenticate=True;EncryptedPassword=False;Host=BLACKPEARL;Port=5555";//Connection string to HostServer
}

_roleManager.Connection.Open(connString);

return _roleManager;
}
}

Then , add a method to read the role items in a K2 blackpearl role (this method returns the role items in semicolon separated format, example: denallix\codi;denallix\anthony)

public string GetK2RoleUsers(string K2Role)
{
Role role = RoleManager.GetRole(K2Role);
string sRoleName = "";

foreach (UserItem UIDel in role.Include)
{
if (sRoleName.Equals(""))
sRoleName += UIDel.Name.Split(":".ToCharArray())[1];
else
sRoleName += ";" + UIDel.Name.Split(":".ToCharArray())[1];
}

return sRoleName.ToLower();
}


To make it clearer , I give a complete code how to use this in a server event code. In this example, I want to get all the role items in a K2 role named "IA" and place the result in K2 DataField named "DestinationApproval"


using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections;
using System.Drawing;
using SourceCode.KO;
using SourceCode.Workflow.Common.Extenders;
using hostContext = Project_5b686e4bb3d24c9b9dfa1d2ef7e5ffb5.EventItemContext_cd0b00f67cf744188529af119ccd3f6b;
using System.Xml;
using System.Xml.XPath;
using SourceCode.Security.UserRoleManager.Management;

namespace ExtenderProject_5b686e4bb3d24c9b9dfa1d2ef7e5ffb5
{
public partial class EventItem_cd0b00f67cf744188529af119ccd3f6b : ICodeExtender<hostContext>
{
//Open Connection to RoleManager
private SourceCode.Security.UserRoleManager.Management.UserRoleManager _roleManager = new SourceCode.Security.UserRoleManager.Management.UserRoleManager();
public void Main(Project_5b686e4bb3d24c9b9dfa1d2ef7e5ffb5.EventItemContext_cd0b00f67cf744188529af119ccd3f6b K2)
{
string userIA = GetK2RoleUsers("IA");
K2.ProcessInstance.DataFields["DestinationApproval"].Value = userIA;
//you can ignore this code below, it's specific to business process of my module :)
XmlDocument doc = new XmlDocument();
string infopathFormName = K2.ProcessInstance.DataFields["InfopathFormName"].Value.ToString();
string xmlString = K2.ProcessInstance.XmlFields[infopathFormName].Value;
string xpathTempUser = K2.ProcessInstance.DataFields["XPathTempUser"].Value.ToString();
doc.LoadXml(xmlString);
XmlNamespaceManager NamespaceManager = InitNamespaceManager(doc);
XPathNavigator root = doc.CreateNavigator();
XPathNavigator node = root.SelectSingleNode(xpathTempUser, NamespaceManager);
node.SetValue(userIA);
K2.ProcessInstance.XmlFields[infopathFormName].Value = doc.InnerXml;

}
public string GetK2RoleUsers(string K2Role)
{
Role role = RoleManager.GetRole(K2Role);
string sRoleName = "";

foreach (UserItem UIDel in role.Include)
{
if (sRoleName.Equals(""))
sRoleName += UIDel.Name.Split(":".ToCharArray())[1];
else
sRoleName += ";" + UIDel.Name.Split(":".ToCharArray())[1];
}

return sRoleName.ToLower();
}
public SourceCode.Security.UserRoleManager.Management.UserRoleManager RoleManager
{
get
{
string connString = string.Empty;

if (_roleManager == null)
_roleManager = new UserRoleManager();

_roleManager.CreateConnection();

if (!_roleManager.Connection.IsConnected)
{
connString = "Integrated=True;IsPrimaryLogin=True;Authenticate=True;EncryptedPassword=False;Host=BLACKPEARL;Port=5555";//Connection string to HostServer
}

_roleManager.Connection.Open(connString);

return _roleManager;
}
}
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;

}
}
}

Monday, December 10, 2007

How to make and use Microsoft Sharepoint Web Part

If you develop applications with MOSS 2007, you likely often make and implement Web Parts in your MOSS 2007 page. Here are some walkthrough / tutorial in making web part. Hope it helps :)

1.- Open Visual Studio 2005.
- Click File - New - Project

2.- On the Project types box, choose Other Project Types - Visual Studio Solutions.
- click Blank Solution form the templates provided.
- Give name for your solution (in my case , the name is MyWebpart and the location is C:\projects\MyWebpart)

3. - On the solution explorer , right click your solution.
- Click Add - new Website.

4. - change Language to Visual C# , then click OK

5. klik File - Add - New Project

6. - Click Visual C# on the project types
- Click Class Library on the Templates , then click OK

7. - On Solution Explorer, right click web site project
- click Add New Item

8. - Click Web User Control on templates
- Give names to your Web User Control (ex: MyGrid.ascx)
- ensure the language is C# , click OK

9. - modify the web user control as you wish (if you want to create your own custom control , skip to step 22)
- in my case , I want to create hierarchical grid using UltraWebGrid control from Infragistics NetAdvantage 2007
- I assume you already have it :D
- drag UltraWebGrid to the design view of MyGrid.ascx
- Infragistics Quick Design dialog show up
- Change the properties as follows:
-- ID : UG1
-- DisplayLayout
---AutoGenerateColumns : False
---ViewType : Hierarchical


10. - next , we have to modify the structure of the grid
- before that, let's look to the sample database diagram
(1 folioname can have 1 or more processname )


11. - next, click Data Structure - Edit Data Structure- Bands and Columns


12. click Column 0 , set the properties as follows :
- BaseColumnName : HeaderID
- Key : HeaderID
- Hidden : True


13. Add new Column


14. repeat step 12 with following properties , then click apply
- BaseColumnName : FolioName
- Key : FolioName
- Hidden : False
- Header
--Caption : Folio Name

15. Add new Band


16. Click the new band, and clik add - column
17. click the new column, change the properties (same with step 12)
- BaseColumnName : HeaderID
- Key : HeaderID
- Hidden : True
18. Click Add - new column (same with step 16)
19. Click the new column, change the properties (same with step 12)
- BaseColumnName : ProcessName
- Key : ProcessName
- Hidden : False
- Header
--Caption : Process Name
then click OK

20. On the code behind of MyGrid.ascx , place this code on Page_Load


SqlConnection con;
SqlDataAdapter daHeader;
SqlDataAdapter daDetail;
DataSet ds;
protected void Page_Load(object sender, EventArgs e)
{
con = new SqlConnection("Data Source=.;Initial Catalog=BSI;Integrated Security=True");
con.Open();
daHeader = new SqlDataAdapter("SELECT * FROM Header", con);
daDetail = new SqlDataAdapter("SELECT * FROM Detail", con);
ds = new DataSet();
daHeader.Fill(ds, "Header");
daDetail.Fill(ds, "Detail");
try
{
ds.Relations.Add("HeaderID", ds.Tables["Header"].Columns["HeaderID"],
ds.Tables["Detail"].Columns["HeaderID"]);
}
catch (Exception ex)
{

Response.Write(ex.Message);
}

UG1.DataSource = ds.Tables["Header"];
UG1.DataBind();
}


21. Don't forget to add using System.Data.SqlClient; on top of your code behind page or by using resolve. Save your work.

22. Open Visual Studio 2005 command prompt
23. type this command
cd \projects\MyWebpart\WebSite1 , press enter
sn -k MyWebpart.snk , press enter


24. go to solution explorer, right click your website project, click Publish Web Site
25. - check the Use Fixed Naming ... checkbox
- check the Enable strong naming ... checkbox
- browse the MyWebpart.snk file made on step 23
- click OK


26. copy DLL file on the PrecompiledWeb folder

to the _app_bin folder of your MOSS
(ex : C:\Inetpub\wwwroot\wss\VirtualDirectories\moss.denallix.com80\_app_bin )


27. - go to solution explorer
- right click the class library projects, click properties
- click Signing tab
- check the Sign the assembly checkbox
- click new


28. - type key file name as you wish (Ex : WebpartLib)
- uncheck Protect my key ... checkbox
- click OK
- click Save


29. - make a new folder in your MOSS folder (ex:C:\Inetpub\wwwroot\wss\VirtualDirectories\moss.denallix.com80) , give name to the folder as you wish , ex: MyUserControl
- place your web user control ( *.ascx and *.ascx.cs) this new folder

30. - go to solution explorer
- right click the class library projects, click add new item
- click Class , give name to it (ex : MyGridWebpart.cs)
- click Add
31. - on the class library projects, right click References folder, click Add reference
- on .NET tab, click System.Web, click OK
- add this code to using section of MyGridWebpart.cs

using System.Web.UI;
using System.Web.UI.WebControls.WebParts;

- don't forget to add public keyword to the class
- inherit the class from Webpart class
- belows are the complete code for MyGridWebpart.cs


using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls.WebParts;
namespace ClassLibrary1
{
public class MyGridWebpart : WebPart
{
private Control child = null;

protected override void CreateChildControls()
{
child = this.Page.LoadControl("~/MyUserControl/MyGrid.ascx");
this.Controls.Add(child);
}

public override void RenderControl(HtmlTextWriter writer)
{
this.EnsureChildControls();
child.RenderControl(writer);
}
}
}


- notice that the path in LoadControl method is the path where you placed your *.ascx and
*.ascx.cs file (in step 29)

32. - on the solution explorer, open AssemblyInfo.cs under the Properties folder in Class library project
- add using System.Security; on using section
- add this code to the last line of the AssemblyInfo.cs
[assembly: AllowPartiallyTrustedCallers()]


33. - right click the class library project, click build
- copy the class library project's DLL (ex : C:\projects\MyWebpart\ClassLibrary1\bin\Debug)

to _app_bin of your MOSS folder (ex :C:\Inetpub\wwwroot\wss\VirtualDirectories\moss.denallix.com80\_app_bin)

34.- go to your MOSS folder (ex : C:\Inetpub\wwwroot\wss\VirtualDirectories\moss.denallix.com80)
- open web.config
- add this code between SafeControls element


<SafeControl Assembly="ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0fb73cb8dfe13eb7"
Namespace="ClassLibrary1" TypeName="*" Safe="True" />


Assembly and Namespace attribute can be retrieved from Project properties (right click Class Library projects, click Application tab)
Version, culture, and PublicKeyToken can be retrived by dragging the project DLL to C:\windows assembly

After you get the PublicKeyToken , uninstall from the assembly

35. - Done, you already made your webpart :)
- you have to do one more thing , add the assembly you used to MOSS web config
if you use native .NET controls, you can skip this. But if you use 3rd party control like
Infragistics etc. You have to do this. Add this code to assemblies element
<add assembly="Infragistics2.WebUI.UltraWebGrid.v7.2, Version=7.2.20072.61, Culture=neutral, PublicKeyToken=7DD5C3163F2CD0CB"/>
<add assembly="Infragistics2.WebUI.Shared.v7.2, Version=7.2.20072.61, Culture=neutral, PublicKeyToken=7DD5C3163F2CD0CB"/>
- Next step is to populate it on Web Parts Gallery
- Open Your MOSS
- Click Site Actions - Site Settings - Modify All Site Settings
- Click Web Parts on Gallery group
- Click new
- check your Webpart checkbox , click Populate Gallery
- your Webpart now show up in the Web part list

36. - You can create a new list to test your web part, or use an existing list
- in my case , I create TestWebpart list
- click TestWebpart list
- click Site Actions - Edit Page
- click Add new webpart , Add Web Parts dialog show up
- click MyGridWebPart checkbox on the Miscellaneous
- click Add
- Your web part has been up :D

Monday, December 3, 2007

How to use web-enabled Infopath form with embedded code with K2 Blackpearl workflow

Microsoft Infopath web-enabled forms by default don't support Infopath code. But there is a way to enable that.

Follow this steps :
* Create a Infopath form aimed to be open in a browser
* Design your form (add the groups and fields, the data connections, etc.) BUT don't add .Net code now (it may work but that's not how I did it)
* Create your K2 project in VS 2005
* Design your workflow just like in the Infopath tutorial provided with the Blackpearl documentation until step 5; this step of the tutorial is the one where you must re-design the form to adapt it. Add your .net code now. When you're done, do not finish the Infopath Integration Wizard.
* In the Infopath Integration Wizard, edit the properties associated to your forms (ie "publish to") and set the form library where you'd like to see your form published. Select "content type" instead of "form library template", and do not forget to set the opening program as "web browser".
* Finish the wizard, and deploy your project
* Now go to the form library, the "settings", and delete all the content types set for this library.
* On the same site, click on "View all site content", you should see a "K2 Blackpearl Form Templates" or something like this. Open the lib. It contains the form you've just deployed. Right-click it, and copy shortcut to this XSN file.
* Go to your MOSS Central Administration, "Application Management" --> "Manage Form Templates", and click on "Upload a form template".
* Click the "Browse" button, paste the shortcut, and click "Ok". This file browser is not made to browse URLs, but it works. (before you paste the shortcut, it's better to choose desktop first to cause it works)
* Confirm the upload of this form template (you can verify it if you want, but it's quite useless)
* Activate it to your site collection
* Go back to your site, and to your form library
* Click "settings", and add an existing content type. In the list, you should find the name of your form (eg: "my form"), plus the name of your form with a suffix which should be "1" (eg: "my form1"). Select this one (the first one is the content type automatically deployed by Blackpearl, do not select it as it's not admin-approved)
* Now go back to the form lib, create a new instance of the form, and.......... it works!!!

This article was taken from this site