Debugging is kind of important when developing a new application. In case of event receiver it is more important as errors are not visible unless they are logged in the text files or in the event log. For event receiver, you cannot start application with F5; you need to set the break point in the code, and wait until item is added or deleted from list.
Furthermore, event receiver DLL needs to be in GAC. It cannot be deployed in the bin folder of web application like web part DLL. It means that, for debugging, your PDB (symbols database) has to be in GAC as well. This is what everybody recommends. Since you can only add DLLs in GAC, there is no straight way how to do that. A simple trick which always works is to place PDB file in the bin folder of web application.
This is the how you can debug event receiver without adding PDB file in the GAC.
1) Right click on project properties of Event Receiver project
2) Go to Build tab
3) Change Output path: to c:\Inetpub\wwwroot\wss\VirtualDirectories\$webApplication$\bin\ where $webApplication$ is you web application folder
4) Build project in Debug mode to create the PDB file and DLL in the \bin of web application
5) If GAC has DLL build in the Release mode, uninstall it
6) Copy or install DLL (Debug mode build) file from web application's \bin folder to (GAC) c:\Windows\Assembly folder
7) Reset IIS Server
8) Hit any page on the SharePoint 2007 web application. It will load W3WP.exe.
9) Attach Debugger to W3WP.exe. If you have multiple W3WP.exe select process by user name
10) Perform add, delete or update operation on a list. Debugger will hit first break point. Make sure to replace DLL in the GAC with every code change.
Friday, July 10, 2009
Thursday, July 2, 2009
SharePoint Navigation - Custom TreeView control
This SPSTreeViewNavigator, a custom asp.net TreeView control provides simple SharePoint sites navigation feature. It can be bundled either in the web part or used on the custom .aspx page to provide site relative navigational TreeView. This control exposes RootWeb property. Set it to SPWeb object of a site. It will create navigational TreeView representing site hierarchy of associated site. When assigned with RootWeb of site collection, it will create navigational TreeView for entire site collection.
TreeView is populated on demand to achieve better performance.
Following is example of client code. Create instance of SPSTreeViewNavigator control and initialize it's RootWeb property with SPWeb object.
TreeView is populated on demand to achieve better performance.
1: using System;
2: using System.Web.UI.WebControls;
3: using System.Xml;
4: using System.Collections;
5: using System.Collections.Generic;
6: using Microsoft.SharePoint;
7: using System.Text.RegularExpressions;
8:
9: namespace YourNameSpace.Controls
10: {
11: public class SPSTreeViewNavigator : TreeView
12: {
13: private SPWeb _rootWeb;
14: public string NODE_IMAGE_URL = "/_layouts/Images/cat.gif";
15:
16: public SPWeb RootWeb
17: {
18: get { return _rootWeb; }
19: set { _rootWeb = value; }
20: }
21:
22: protected override void OnLoad(EventArgs e)
23: {
24: base.OnLoad(e);
25: InitializeTreeView();
26: }
27:
28: //Populate TreeView on demand
29: void DataViewTreeView_TreeNodePopulate(object sender, TreeNodeEventArgs e)
30: {
31: PopulateChildNodes(e.Node);
32: }
33:
34: void InitializeTreeView()
35: {
36: this.Height = Unit.Percentage(100);
37: this.Width = Unit.Percentage(100);
38: this.ShowCheckBoxes = TreeNodeTypes.All;
39: this.EnableClientScript = true;
40: this.ShowExpandCollapse = true;
41: //View State must be enable
42: this.EnableViewState = true;
43: this.ShowLines = true;
44: this.TreeNodePopulate += DataViewTreeView_TreeNodePopulate;
45: this.NodeStyle.ImageUrl = NODE_IMAGE_URL;
46: if (!this.Page.IsPostBack)
47: {
48: this.Nodes.Clear(); PopulateRootNode(this);
49: }
50: }
51:
52: void PopulateChildNodes(TreeNode node)
53: {
54: Guid webGuidId = new Guid(node.Value);
55: using (SPSite spSite = new SPSite(_rootWeb.Site.ID))
56: {
57: using (SPWeb web = spSite.OpenWeb(webGuidId))
58: {
59: foreach (SPWeb spWeb in web.Webs)
60: {
61: PopulateTreeNode(spWeb, node);
62: }
63: }
64: }
65: }
66:
67: private void PopulateTreeNode(SPWeb web, TreeNode node)
68: {
69: TreeNode newNode = new TreeNode(web.Title, web.ID.ToString(),
70: NODE_IMAGE_URL, web.ServerRelativeUrl, string.Empty); newNode.PopulateOnDemand = true;
71: newNode.Expanded = false;
72: newNode.SelectAction = TreeNodeSelectAction.SelectExpand;
73: node.ChildNodes.Add(newNode);
74: }
75:
76: //Populate root node and next level child nodes
77: void PopulateRootNode(TreeView treeView)
78: {
79: TreeNode node = new TreeNode();
80: SPWeb web = _rootWeb; node.Text = web.Title;
81: node.Value = web.ID.ToString();
82: node.NavigateUrl = web.ServerRelativeUrl;
83: node.PopulateOnDemand = true;
84: node.ShowCheckBox = true;
85: node.Expand();
86: treeView.Nodes.Add(node);
87: }
88: }
89: }
90:
91:
92:
Following is example of client code. Create instance of SPSTreeViewNavigator control and initialize it's RootWeb property with SPWeb object.
1: SPSTreeViewNavigator treeView = new SPSTreeViewNavigator();
2: treeView.RootWeb = SPContext.Current.Site.OpenWeb();
3: Controls.Add(treeView);
Following image shows SPSTreeViewNavigator in action, with TreeView fully expanded.
Wednesday, July 1, 2009
Auto Publish documents in SharePoint 2007
SharePoint 2007 allows check-in, check out, publish and approve documents in the document libraries. This can be achieved via SharePoint object model. Here is an example in C#.
This code snippet will work for document libraries with 'Required Approval' disabled as well as enabled. If you try to approve document which does not require approval, exception will be generated.
This code snippet will work for document libraries with 'Required Approval' disabled as well as enabled. If you try to approve document which does not require approval, exception will be generated.
1: private void publish(SPWeb web, string listName)
2: {
3: SPList list = web.Lists[listName];
4: web.AllowUnsafeUpdates = true;
5: foreach (SPListItem item in list.Items)
6: {
7: SPFile sourceFile = item.File;
8: try
9: {
10: if (sourceFile.Level == SPFileLevel.Draft sourceFile.Level == SPFileLevel.Checkout)
11: {
12: //Check in file
13: if (sourceFile.CheckOutStatus != SPFile.SPCheckOutStatus.None)
14: sourceFile.CheckIn("System CheckIn", SPCheckinType.MajorCheckIn);
15:
16: //Submit file for content approval
17: sourceFile.Publish("System published.");
18:
19: //Approve file if 'Require content approval for submitted items' is enabled
20: //Exception will occur trying to approve document which doesn't require approval
21: if (sourceFile.Item.ModerationInformation != null)
22: {
23: if (sourceFile.Item.ModerationInformation.Status == SPModerationStatusType.Pending)
24: sourceFile.Approve("System approved.");
25: }
26: sourceFile.Update();
27: _publishedDocuments.Append("<br>" + web.Url + "/" + sourceFile.Url);
28: }
29: }
30: catch (System.Exception ex)
31: {
32: //handle exception here
33: }
34: }
35: web.AllowUnsafeUpdates = false;
36: }
Subscribe to:
Posts (Atom)