Tuesday, September 15, 2009

Nunit for unit testing

Recently I installed .net 3.5 and visual studio 2008 on a new machine. Created one project and tried running the NUnit on the DLL but it gave me an exception called System.badImage... I tried with sample Arithmatic application available on web, but still the same error. When I saw the CLR version of NUnit using Help menu, it showed 1.1... I found the gui.exe.config file and amended the entries in there and added for 3.5... whew it started working
<startup>
<supportedRuntime version="v3.5.7121"/>
<supportedRuntime version="v3.5" />
<supportedRuntime version="v2.0.50727" />
<supportedRuntime version="v2.0.40301" />
<supportedRuntime version="v1.1.4322" />
<supportedRuntime version="v1.0.3705" />
<requiredRuntime version="v1.0.3705" />
</startup>

If you are new to NUnit then browse at samuel's blog, he has written excellent post to begin with nUnit.

Testing self app is always good.

Friday, September 4, 2009

Using Triple DES, creating Keys and IV

Many a times I come with across doing encryption/decryption stuff. Just learned about TripleDES which is now being recommended as one of the best encryption algo. Long time back I dealt with issue of generating Key and using 3DES with this key. I was not able to find out a complete solution anywhere on web. Ahh but ppl came around asking again for this .. hopefully you will find this useful.

I am creating a web site application (so not a MOSS post this time) which will encrypt, decrypt and generate MachineKey using your private key. This machine key is needed if you dont want your clear text private key to be stored/communicate over net.

This is VS2008 web site cs file code snippet below

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Security.Cryptography;
using System.Text;
public partial class KeyFor3DES : System.Web.UI.Page
{
private string Key = "MyNameIsAmitabhWankhede";
private readonly byte[] IVector = new byte[8] { 55, 26, 80, 63, 100, 82, 46, 120 };
protected void Page_Load(object sender, EventArgs e)
{
string inpstring = "This is some secured data which needs to be encrypted";
Response.Write(Encrypt(inpstring));
Response.Write("
");
Response.Write(Decrypt(Encrypt(inpstring)));
Response.Write("
");
TripleDESCryptoServiceProvider myKey = GetKey(Key);
Response.Write("
");
Response.Write(CreateMachineKeyFor3DES(48, myKey.Key));
}
private string Encrypt(string inputString)
{
byte[] buffer = Encoding.ASCII.GetBytes(inputString);
TripleDESCryptoServiceProvider tripleDes = GetKey(Key);
ICryptoTransform ITransform = tripleDes.CreateEncryptor();
return Convert.ToBase64String(ITransform.TransformFinalBlock(buffer, 0, buffer.Length));
}
private string Decrypt(string inputString)
{
byte[] buffer = Convert.FromBase64String(inputString);
TripleDESCryptoServiceProvider tripleDes = GetKey(Key);
ICryptoTransform ITransform = tripleDes.CreateDecryptor();
return Encoding.ASCII.GetString(ITransform.TransformFinalBlock(buffer, 0, buffer.Length));
}
private TripleDESCryptoServiceProvider GetKey(string pKey)
{
TripleDESCryptoServiceProvider tripleDes = new TripleDESCryptoServiceProvider();
MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider();
tripleDes.Key = MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(pKey));
tripleDes.IV = IVector;
return tripleDes;
}

public string CreateMachineKeyFor3DES(int length, byte[] randomBytes)
{
//byte[] randomBytes = new byte[length / 2];
RNGCryptoServiceProvider rngProvider = new RNGCryptoServiceProvider();
//Fill the bytearray with random bytes
rngProvider.GetBytes(randomBytes);
//Stringbuilder to hold result once convertd to hexadecimal
StringBuilder strBldrMacKey = new StringBuilder(length);
//loop thru the random byte and append each value to strin builder
for (int i = 0; i < randomBytes.Length; i++)
{
strBldrMacKey.Append(string.Format("{0:X2}",randomBytes[i]));
}
return strBldrMacKey.ToString();
}
}

Monday, August 31, 2009

Disable /Readonly /Hiding a form field in newform.aspx

Never thought that I could disallow user to edit a field in newform.aspx using simple javascript function. As soon as the page gets loaded i m finding the input box (need to disable a input field if you need to disable any other field change the params for getTagFromIdentifierAndTitle) and disabling it, so user cannot modify it. One can make use of the PreSaveAction function which is always called before request gets posted to server, where I am re-enabling the textbox.

Need to copy this Javascript function in newform.aspx with the help of Sharepoint designer in Placeholder main. Remember that I have a list with column name JSReadOnly so one will change it if they are having some other name. I havent tried but I hope it should also work field types other than TextField with little change.

function PreSaveAction()
{
var field = getTagFromIdentifierAndTitle("INPUT","TextField","JSReadOnly");
//alert(field.value);
field.disabled=false;
setTimeout('setFieldDisable()',1000);
return true;
}

function getTagFromIdentifierAndTitle(tagName, identifier, title)
{
var len = identifier.length;
var tags = document.getElementsByTagName(tagName);
for (var i=0; i < tempstring =" tags[i].id;" title ="=" identifier ="=">

function setFieldDisable()
{
var field1 = getTagFromIdentifierAndTitle("INPUT","TextField","JSReadOnly");
if(field1!=null)
field1.disabled=true;
else
setTimeout('setFieldDisable()',500);
}

setTimeout('setFieldDisable()',500);



Beware that there are pros and cons of SPD :)

Friday, August 7, 2009

Chrome Type and Title getting blank

Today one issue kept me real busy. Somehow I was able to solve.

The issue I faced was, after saving the properties of the webpart the "Title" and "Chrome Type" of webpart was getting blank. Weird, but it was working some days ago.

Googled it but couldn't find any solution. Aha I like it when I stuck with something new unique problem... sometimes gotta use my own head.
Thought may be either of the overridden method must be getting failed but in each method Try Catch was taking care of this.
I noticed that some of the custom properties were able to save themselves and retained their values, quite amazing. So thought some Custom Properties might be throwing error .... bingo

In one of the property I had used page.session to get and set value.

public string StringTopicID
{
get
return Convert.ToString(Page.Session["ID"]);
}
set
{
Page.Session["ID"] = value;
}
}
I cleared the code

public string StringTopicID
{
get { return "125";}
set { ; }
}
And it work back again, I was able to retain the value of Title and Chrome Type.... wow.
Removed the session thing and used viewstate instead

I am still finding the exact reason... Will update once I got time to find it.

Long live Mi ros ft, luv U!!!

Wednesday, July 15, 2009

Feature ActivationDependencies

Earlier I have associated certain workflows in FeatureActivate method inside featurereceiver.. But one point to remember is that these workflows must be already activated on site scope, in order to associate the workflow with lists.

So I have two features
1. Workflow Feature
2. Association Feature
the workflow feature look like below


Version="12.0.0.0"
Scope="Site"
ReceiverAssembly="Microsoft.Office.Workflow.Feature, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
ReceiverClass="Microsoft.Office.Workflow.Feature.WorkflowFeatureReceiver"
xmlns="http://schemas.microsoft.com/sharepoint/">












WORKFLOW.xml



Id=""
CodeBesideClass="ASSEMBLY.Workflow1"
CodeBesideAssembly="ASSEMBLY, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6e563d29ec4ce4ae"
TaskListContentTypeId="0x01080100C9C9515DE4E24001905074F980F93160"
ModificationUrl="_layouts/ModWrkflIP.aspx">



false
_layouts/WrkStat.aspx




WORKFLOWUPDATE.xml



Id=""
CodeBesideClass="ASSEMBLY.UpdateForumFields"
CodeBesideAssembly="ASSEMBLY, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6e563d29ec4ce4ae"
TaskListContentTypeId="0x01080100C9C9515DE4E24001905074F980F93160"
ModificationUrl="_layouts/ModWrkflIP.aspx">



false
_layouts/WrkStat.aspx




FEATURE 2-->

Title="Attaching WFs"
Description="Feature Receiver for Attaching WFs"
Version="1.0.0.0"
Scope="Web"
ReceiverAssembly="ASSEMBLY2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3b623d2d8fcb1e2a"
ReceiverClass="ASSEMBLY2.DiscussionFeatureReceiver"
xmlns="http://schemas.microsoft.com/sharepoint/"
>




Associating workflow with List, SPWorkflowAssociation, CreateListAssociation

The best place to me attach workflow to a list is inside the FeatureReceiver's activated method and to revoke this place remove method inside FeatureReciever's deactivated event
I have already discuss about creating feature receiver, so just focusing here is the SPWorkflowAssociation and CreateListAssociation.
In FeatureActivated method call this method with listInstance, string containig WF GUID, a workfow Association name and the web.

public void AddDFWorkflow(SPList myList, string workflowTemplateGuid, string workflowAssocName, SPWeb web)
{
//myList // List to associate workflow to
SPList historyList = null; // Workflow history list
SPList taskList = null; // Workflow tasks list
//workflowTemplateGuid // Workflow template Guid
SPWorkflowTemplate workflowTemplate = null; // Workflow template
SPWorkflowAssociation workflowAssociation = null; // Workflow association
//workflowAssocName // Workflow association name
workflowTemplate = web.WorkflowTemplates[new Guid(workflowTemplateGuid)];
try
{
historyList = web.Lists["Workflow History"];
}
catch (ArgumentException exc)
{
// Create workflow history list
Guid listGuid = web.Lists.Add("Workflow History", "", SPListTemplateType.WorkflowHistory);
historyList = web.Lists[listGuid];
historyList.Hidden = true;
historyList.Update();
}
try
{
taskList = web.Lists["Workflow Tasks"];
}
catch (ArgumentException exc)
{
// Create workflow tasks list
Guid listGuid = web.Lists.Add("Workflow Tasks", "", SPListTemplateType.Tasks);
taskList = web.Lists[listGuid];
taskList.Hidden = true;
taskList.Update();
}
web.AllowUnsafeUpdates = true;
try
{
// Create workflow association
workflowAssociation = SPWorkflowAssociation.CreateListAssociation(workflowTemplate, workflowAssocName, taskList, historyList);
// Set workflow parameters
workflowAssociation.AllowManual = false;
workflowAssociation.AutoStartCreate = false;
workflowAssociation.AutoStartChange = false;
// Add workflow association to my list
myList.AddWorkflowAssociation(workflowAssociation);
// Enable workflow
workflowAssociation.Enabled = true;
}
catch (Exception ex)
{ }
finally
{
web.AllowUnsafeUpdates = false;
}
}

In feature deactivated method call this method

public void RemoveDFWorkflow(SPList myList, string workflowAssocName, SPWeb web)
{
try
{
if (myList.WorkflowAssociations.Count > 0)
{
SPWorkflowAssociation _association = null;
foreach (SPWorkflowAssociation association in myList.WorkflowAssociations)
{
if (association.Name.Equals(workflowAssocName))
{
_association = association;
break;
}
}
if (_association != null)
myList.RemoveWorkflowAssociation(_association);
myList.Update();
}
}
catch (Exception ex)
{}
}


Enjoy!!!

Starting workflow Programmatically using object model SPWorkflowAssociationCollection , SPWorkflowAssociation, SPWorkflowManager

We will discuss here how to start the SharePoint workflow dynamically in an Event receiver. I am using ItemAdded Event to start the workflow, if mail settings are allowed, to send group mails instantaneously

I have earlier discuss about creating event receiver and how to associate it with List. Lets focus here for now on starting the workflow

public override void ItemAdded(SPItemEventProperties properties)
{
try
{
base.ItemAdded(properties);
if (isGlobalMailAllowed(properties))
{
//Mails are allowed at site level, start workflow to send mails
StartThisWorkflow(properties, strWorkflowAlertGUID);
}
}
catch (Exception ex)
{}
}



///
/// Starts a workflow associated to a list programmatically.
///

///
///
private void StartThisWorkflow(SPItemEventProperties properties, string strWorkflowID)
{
try
{
SPListItem listItem = properties.ListItem;
SPWeb web = properties.OpenWeb(); //Following best programming practices for Event handler to get spweb object
SPSite site = web.Site;
SPWorkflowManager manager = site.WorkflowManager;
SPList parentList = listItem.ParentList;
SPWorkflowAssociationCollection associationCollection = parentList.WorkflowAssociations;
LookupAndStartWorkflow(listItem, manager, associationCollection, strWorkflowID);
}
catch (Exception ex)
{}
}

///
/// Lookup and start the workflow.
///

///
///
///
///
private static void LookupAndStartWorkflow(SPListItem listItem, SPWorkflowManager manager,
SPWorkflowAssociationCollection associationCollection,
string workflowId)
{
foreach (SPWorkflowAssociation association in associationCollection)
{
Guid workflowGuid = new Guid(workflowId);
if (association.BaseId == workflowGuid)
{
string data = association.AssociationData;
SPWorkflow wf = manager.StartWorkflow(listItem, association, data);
}
}
}

Thanks to the miguelisidoro @
http://blogit.create.pt/blogs/miguelisidoro/archive/2008/07/05/SharePoint-2007-_2D00_-Start-a-Workflow-Programmatically.aspx

Cheers!!!

ListItemCollectionPosition, PagingInfo, SPQuery and paging in SharePoint

Finally got time to post after many days, hope to write all important stuff today..

Using inbuilt paging provided by SPListItemCollectionPosition, used with SPQuery....

I have used treeview control and am providing paging control (prev and next) options to it. Next will take it to the next set of paged responses. Using ajax to avoid post backs.

Lets create the webpart


protected TreeView tvSample;
LinkButton lnkBtnNextPage;
LinkButton lnkBtnPrevPage;
UpdatePanel updatePanelMain;
ArrayList arrListPrevPages;
private uint intPageSize;
private int intTopicID;


[WebBrowsable(true)]
[Personalizable(PersonalizationScope.Shared)]
[WebDescription("configure the Discussion tree per page size")]
[Category("Discussion Tree Properties")]
public uint PageSize
{
get
{
if (intPageSize == 0)
return 2;
else
return intPageSize;
}
set { intPageSize = value; }
}

[WebBrowsable(true)]
[Personalizable(PersonalizationScope.Shared)]
[WebDescription("configure the Discussion tree topic display")]
[Category("Discussion Tree Properties")]
public int TopicID
{
get {
if (intTopicID == 0)
return 125;
else
return intTopicID;
}
set { intTopicID = value; }
}
[Personalizable(PersonalizationScope.User)]
public string TreeRenderedVS
{
get { return Convert.ToString(ViewState["TreeRenderedVS"]); }
set { ViewState["TreeRenderedVS"] = value; }
}
[Personalizable(PersonalizationScope.User)]
public ArrayList ArrListPrevPages
{
get { return (ArrayList)ViewState["ArrListPrevPagesVS"]; }
set { ViewState["ArrListPrevPagesVS"] = value; }
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}
protected override void CreateChildControls()
{
base.CreateChildControls();
FixFormAction();
this.updatePanelMain = new UpdatePanel();
this.updatePanelMain.ID = "updatePanelMain";
this.tvSample = new TreeView();
tvSample .ID = "responsesTreeView";
tvSample .CssClass = "TreeView1";
tvSample .Width = 950;
tvSample .ExpandImageToolTip = "Click here to expand";
tvSample .CollapseImageToolTip = "Click here to collapse";
tvSample .ExpandImageUrl = "bluearrow.gif";
tvSample .CollapseImageUrl = "_layouts/redarrow.gif";
tvSample .ParentNodeStyle.VerticalPadding = 0;
tvSample .NodeStyle.ChildNodesPadding = 0;
tvSample .NodeStyle.NodeSpacing = 0;
tvSample .NodeStyle.VerticalPadding = 0;
tvSample .NodeStyle.Width = Unit.Pixel(950);
tvSample .ToolTip = "";
tvSample.EnableClientScript = false;
this.tvSample.TreeNodePopulate += new TreeNodeEventHandler(Node_Populate);
TreeNode node = new TreeNode("Discussion","0");
tvSample.Nodes.Add(node);
this.lnkBtnNextPage = new LinkButton();
this.lnkBtnNextPage.ID = "lnkBtnNextPage";
this.lnkBtnNextPage.Text = "Next";
this.lnkBtnNextPage.Click += new EventHandler(lnkBtnNextPage_Click);

this.lnkBtnPrevPage = new LinkButton();
this.lnkBtnPrevPage.Text = "Previous";
this.lnkBtnPrevPage.ID = "lnkBtnPrevPage";
lnkBtnPrevPage.Click += new EventHandler(lnkBtnPrevPage_Click);
this.updatePanelMain.ContentTemplateContainer.Controls.Add(this.tvSample);
this.updatePanelMain.ContentTemplateContainer.Controls.Add(this.lnkBtnPrevPage);
this.updatePanelMain.ContentTemplateContainer.Controls.Add( new LiteralControl(" "));
this.updatePanelMain.ContentTemplateContainer.Controls.Add(this.lnkBtnNextPage);
this.Controls.Add(this.updatePanelMain);
if (TreeRenderedVS.Equals(String.Empty))
{
TreeRenderedVS = "Yes";
populateNodes();
}
arrListPrevPages = new ArrayList();
lnkBtnPrevPage.Attributes.Add("style", "display:none;");
}


protected override void OnPreRender(EventArgs e)
{
base.EnsureChildControls();
base.OnPreRender(e);
}

protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
}

private void FixFormAction()
{
if (this.Page.Form != null)
{
string formOnSubmitAtt =
this.Page.Form.Attributes["onsubmit"];
if (formOnSubmitAtt == "return _spFormOnSubmitWrapper();")
{
this.Page.Form.Attributes["onsubmit"] =
"_spFormOnSubmitWrapper();";
}
}
ScriptManager.RegisterStartupScript(this, typeof(VoicesDF), "UpdatePanelFixup", "_spOriginalFormAction = document.forms[0].action;_spSuppressFormOnSubmitWrapper=true;", true);
}

Now get treeview populated using the following code, I am using onDemand population of child nodes


protected void populateNodes()
{
tvSample.Nodes.Clear();
TreeNode tnodeDis = new TreeNode("Discussion", "0");
tnodeDis.Expand();
tvSample.Nodes.Add(tnodeDis);
DataTable dtReplies = GetActiveResponsesLevel0("MostRecent", Convert.ToInt32(TopicID), "Discussion Forum");
for (int i = 0; i < newnode =" new" populateondemand =" true;" selectaction =" TreeNodeSelectAction.None;">public void Node_Populate(object sender, System.Web.UI.WebControls.TreeNodeEventArgs e)
{
if (e.Node.ChildNodes.Count == 0)
{
switch (e.Node.Depth)
{
case 0:
FillRootResp(e.Node);
break;
default:
FillReplies(e.Node);
break;
}
}
}
public void FillRootResp(TreeNode node)
{
DataTable dtReslev0 = GetActiveResponsesLevel0("MostRecent", Convert.ToInt32("125"), "Discussion Forum");
for (int i = 0; dtReslev0 != null && i < newnode =" new" populateondemand =" true;" selectaction =" TreeNodeSelectAction.None;">public void FillReplies(TreeNode node)
{
DataTable dtReplies = GetActiveReplies("MostRecent", Convert.ToInt32(node.Value), "Discussion Forum");
for (int i = 0; dtReplies != null && i < newnode =" new" populateondemand =" true;" selectaction =" TreeNodeSelectAction.None;">public DataTable GetActiveResponsesLevel0(string view, int QuestionId, string messageBoardName)
{
DataTable dtResponses = null;
using (SPSite site = new SPSite(strMysiteURL))
{
using (SPWeb web = site.OpenWeb(strMyWebURL))
{
SPQuery query;
string orderByQuery = string.Empty;

query = new SPQuery();
StringBuilder queryText = new StringBuilder();
queryText.Append("");
queryText.Append("");
queryText.Append("");
queryText.Append(QuestionId.ToString());
queryText.Append("
");
queryText.Append("1");
queryText.Append("
");
queryText.Append("
");
if (view.Equals("MostRecent"))
{
orderByQuery = "";
}
else if (view.Equals("Author"))
{
orderByQuery = "";
}
else if (view.Equals("Title"))
{
orderByQuery = "";
}
queryText.Append(orderByQuery);
query.Query = queryText.ToString();
//query.InnerXml = string.Empty;
query.ViewAttributes += " Scope=\"Recursive\"";
query.RowLimit = PageSize; // that is our page size
SPListItemCollection itemColl = null; //This will be used for paging
if (Page.Session["ListItemCollectionPosition"] == null && Convert.ToString(Page.Session["ListItemCollectionPosition"]).Equals(string.Empty))
{
itemColl = web.Lists[messageBoardName].GetItems(query);
}
else
{
//query.ListItemCollectionPosition = (SPListItemCollectionPosition)Page.Session["ListItemCollectionPosition"]; //U cannot store ListItemCollectionPosition in Session (NSer)
string strPagingInfo = Convert.ToString(Page.Session["ListItemCollectionPosition"]); //Compiled paging info, of next page... get it from session
SPListItemCollectionPosition itmPosn = new SPListItemCollectionPosition(strPagingInfo); //Atleast the contructor is helpful here
query.ListItemCollectionPosition = itmPosn; //Update the spquery object so as to query this sessioned page
itemColl = web.Lists[messageBoardName].GetItems(query); //retrieve the paged data
}
dtResponses = itemColl.GetDataTable();
if (itemColl.ListItemCollectionPosition != null)
{
Page.Session["ListItemCollectionPositionNext"] = itemColl.ListItemCollectionPosition.PagingInfo; //Store the paginginfo in session so for next time it will be used, instead of new SPQuery
lnkBtnNextPage.Attributes.Add("style", "display:inline;");
}
else
{
Page.Session["ListItemCollectionPositionNext"] = null;
lnkBtnNextPage.Attributes.Add("style", "display:none;");
}
Page.Session["Added"] = "true";
}
}
// });
if (dtResponses != null)
return dtResponses;
else
return null;
}

//For all child replies
public static DataTable GetActiveReplies(string view, int QuestionId, string messageBoardName)
{
DataTable dtResponses = null;
using (SPSite site = new SPSite(strMySiteURL))
{
using (SPWeb web = site.OpenWeb(strMyWebURL))
{
SPQuery query;
string orderByQuery = string.Empty;
query = new SPQuery();
StringBuilder queryText = new StringBuilder();
queryText.Append("");
queryText.Append("");
queryText.Append("");
queryText.Append(QuestionId.ToString());
queryText.Append("
");
queryText.Append("1");
queryText.Append("
");
queryText.Append("
");
if (view.Equals("MostRecent"))
{
orderByQuery = "";
}
else if (view.Equals("Author"))
{
orderByQuery = "";
}
else if (view.Equals("Title"))
{
orderByQuery = "";
}
queryText.Append(orderByQuery);
query.Query = queryText.ToString();
//query.InnerXml = string.Empty;

query.ViewAttributes += " Scope=\"Recursive\"";
dtResponses = web.Lists[messageBoardName].GetItems(query).GetDataTable();
}
}
// });
if (dtResponses != null)
return dtResponses;
else
return null;
}

//Below two function for formatting the node and adding some details to it.
private string GetFormattedText(DataRow dr)
{
StringBuilder nodeText = new StringBuilder();
string responseTitle = string.Empty;
string responseBody = string.Empty;
string authorPId = string.Empty;
string createdDate = string.Empty;
string userName = string.Empty;
int comments = 0;
string totalResponse = string.Empty;
bool boolDisplayYourName = true;
const string strAnonymous = "Anonymous";


responseTitle = dr["Body"].ToString();
authorPId = dr["AuthorPId"].ToString();
if (dr["AuthorName"] != null)
userName = dr["AuthorName"].ToString();
createdDate = Convert.ToDateTime(dr["created"].ToString()).ToShortDateString();
string strDisplayYourName = dr["DisplayYourName"].ToString().Trim();
if (strDisplayYourName.Trim() == "1")
boolDisplayYourName = true;
else if (strDisplayYourName.Trim() == "0")
boolDisplayYourName = false;
totalResponse = responseTitle;
totalResponse += " (" + comments.ToString() + ") ";
totalResponse += " (" + createdDate + ") ";
if (comments > 0)
{
if (boolDisplayYourName == true)
totalResponse += "" + " by " + userName + "";
else
totalResponse += "" + " by " + strAnonymous + "";


}
else
{
if (boolDisplayYourName == true)
totalResponse += "" + " by " + userName + "";
else
totalResponse += "" + " by " + strAnonymous + "";


}
nodeText.Append("

");
nodeText.Append(" ");
if (comments > 0)
nodeText.Append(" ");
nodeText.Append("
");
nodeText.Append("
");
else
nodeText.Append("
");
nodeText.Append(totalResponse);
nodeText.Append("
");
return nodeText.ToString();

}


private string GetFormattedText(DataRow dr, int iDepth)
{
StringBuilder nodeText = new StringBuilder();
string responseTitle = string.Empty;
string responseBody = string.Empty;
string authorPId = string.Empty;
string createdDate = string.Empty;
string userName = string.Empty;
int comments = 0;
string totalResponse = string.Empty;
bool boolDisplayYourName = true;
const string strAnonymous = "Anonymous";
responseTitle = dr["Body"].ToString();
authorPId = dr["AuthorPId"].ToString();
if (dr["AuthorName"] != null)
userName = dr["AuthorName"].ToString();
createdDate = Convert.ToDateTime(dr["created"].ToString()).ToShortDateString();
string strDisplayYourName = dr["DisplayYourName"].ToString().Trim();
if (strDisplayYourName.Trim() == "1")
boolDisplayYourName = true;
else if (strDisplayYourName.Trim() == "0")
boolDisplayYourName = false;
totalResponse = responseTitle;
totalResponse += " (" + comments.ToString() + ") ";
totalResponse += " (" + createdDate + ") ";
if (comments > 0)
{
if (boolDisplayYourName == true)
totalResponse += "" + " by " + userName + "";
else
totalResponse += "" + " by " + strAnonymous + "";
}
else
{
if (boolDisplayYourName == true)
totalResponse += "" + " by " + userName + "";
else
totalResponse += "" + " by " + strAnonymous + "";
}
if (iDepth > 0)
nodeText.Append("

");
else
nodeText.Append(" ");
nodeText.Append(" ");
if (comments > 0)
nodeText.Append(" ");
nodeText.Append("
");
nodeText.Append("
");
else
nodeText.Append("
");
nodeText.Append(totalResponse);
nodeText.Append("
");
return nodeText.ToString();
}

The important method is GetActiveResponsesLevel0 for paging, other method mostly help with treeview.

Happy programming!!!


Thursday, June 25, 2009

Feature receiver and ItemEvent Receiver

When writing Item Event receiver one way to register the event with list is using Feature Receivers. I will go through this approach in this post. What is really needed to modify lists by adding event receivers to the list in the FeatureActivated event and doing reverse i.e. deleting the Item event in Feature deactivating event. However SPFeature Receiver contains all abstract method so you will need to override them as well.

public class DFeatureReceiver: SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWeb MyCurrentWeb = properties.Feature.Parent as SPWeb;
SPSecurity.RunWithElevatedPrivileges(delegate
{
using (SPSite site = new SPSite(MyCurrentWeb.Site.ID))
{
using (SPWeb web = site.OpenWeb(MyCurrentWeb.ID))
{
SPList listDisc = web.Lists["My List"];
string strTypeName = Assembly.GetExecutingAssembly().FullName;
string strReceiverClass = "a.b.c.DIReciever";
if(listDisc!=null)
{
listDisc.EventReceivers.Add(SPEventReceiverType.ItemAdded, strTypeName, strReceiverClass);
}
}
}
});
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
SPWeb MyCurrentWeb = properties.Feature.Parent as SPWeb;
SPSecurity.RunWithElevatedPrivileges(delegate
{
using (SPSite site = new SPSite(MyCurrentWeb.Site.ID))
{
using (SPWeb web = site.OpenWeb(MyCurrentWeb.ID))
{
SPList listDisc = web.Lists["My List"];
string strTypeName = Assembly.GetExecutingAssembly().FullName;
SPEventReceiverDefinitionCollection evntRecDefnColl = listDisc.EventReceivers;
Guid[] arrGuids = new Guid[evntRecDefnColl.Count];
int intCtr = 0;
foreach (SPEventReceiverDefinition erd in evntRecDefnColl)
{
if (erd.Assembly.ToLower().Equals(strTypeName.ToLower()))
{
arrGuids[intCtr++] = erd.Id;
}
}
Guid guidTmp = new Guid("{00000000-0000-0000-0000-000000000000}");

for (int i = 0; i < arrGuids.Length; i++)
{
if (arrGuids[i] != null && arrGuids[i] != guidTmp)
{
evntRecDefnColl[arrGuids[i]].Delete();
}
}

}
}
});
}
catch (Exception ex)
{}
}

Now moving on to Item Event reciever just inherit class from SPItemEventReceiver and override the methods .. remember one thing that all ...ing events are before events and ...ed events are after events (generally written as async event but doesnt executes asynchronously)


public class DIReciever: SPItemEventReceiver
{
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
SPListItem lstItem= properties.ListItem;

}
}

Wednesday, June 10, 2009

Using MultiLookupField & Richtextfield in a webpart

Earlier I tried to use MultiLookUpField in my webpart but got stuck with one issue. Later on I was able to correct it. To use multilookup in your webpart you will need to make sure that ID is either a HardCoded value or the check for the Field.Title whether it doesnt any blank space in it.
SPList CurrentList = myDestinationListWithReferrerLookupField;
multiLookup.ID = "multiLookupID";
multiLookup.ListId = CurrentList.ID;
multiLookup.FieldName = Field.Title;
multiLookup.ControlMode = SPControlMode.New;
multiLookup.ItemId = CurrentList.Items[0].ID;
this.Controls.Add(multiLookup);

Now to retrieve the value selected by user is quite straight forward, just do
multiLookup.Value, which will return an object to be assigned to MultiLookup field
itm["MyLookUpReferrer"] = multiLookup.Value;

One thing I was quite amazed to see was that while creating multilookupfield control there was no need to assign anywhere the SourceLookupField, I guess that below
multiLookup.ItemId = CurrentList.Items[0].ID
line does the job for us.

Now adding RichTextField to a webpart is straightforward , just need to remember to give ID value of the List which contains a column with "Multiple lines of text", The "Field" below refers to such column.
txtRichDiscript.ID = "txtRichDiscript";
txtRichDiscript.ListId = CurrentList.ID;
txtRichDiscript.FieldName = Field.Title;
txtRichDiscript.ControlMode = SPControlMode.New;
this.Controls.Add(txtRichDiscript);

Wednesday, June 3, 2009

Backup and Restore

Today I have worked on backing and restoring myapplication site collection.

It is made simpler thanks to STSADM commands.

stsadm –o backup –url http://MySourceSiteColl/ -filename D:\Backup.dat -overwrite
stsadm –o restore –url http://MyNewBlankWebApp/ -filename D:\Backup.dat

There are also Stsadm command to import or export a particular site

(note: complete site collection cannot be imported or exported but rather subsites)

Tuesday, June 2, 2009

Store values inside MultipleLookupField of Sharepoint list

Adding value to a column which is referring to some list for data is not so straight forward. You will need to use SPFieldLookupValueCollectionand, where all the Lookup values will be added along with their source ID. I had use ListBox which contains all the value selected by user which needs to be added to list having MultipleLookupfield.
SPFieldLookupValueCollection lookupValCollection = new SPFieldLookupValueCollection();
SPList listMultiSource = SourceListWhichIsReferred
if (listMultiSource != null)
{
foreach (ListItem listBoxJSelected in listBoxJ.Items)
{
if (listBoxJSelected.Selected == true)
{
foreach (SPListItem listMultiSourceItem in listMultiSource.Items)
{
string strJTitle = Convert.ToString(listMultiSourceItem["Title"]);
if (strJFTitle.Equals(listBoxJSelected.Value))
{
int iD = Convert.ToInt32(listMultiSourceItem["ID"]);
SPFieldLookupValue lookupVal = new SPFieldLookupValue(iD, listBoxJSelected.Value);
lookupValCollection.Add(lookupVal);
}
}
}
}itm["J"] = lookupValCollection;
}
itm.update();