SharePoint Site Recycle Bin for SharePoint 2010

The SharePoint Site Recycle Bin for SharePoint 2010 is available for download at http://governance.codeplex.com.

The SharePoint Site Recycle Bin is a SharePoint Foundation 2010 solution package that when deployed to a Microsoft SharePoint Foundation 2010 or Microsoft SharePoint Server 2010 server farm enables administrators to create a snapshot of subscriptions, site collections and Webs as they are deleted through the SharePoint user interface, the SharePoint Administration Tool, the SharePoint 2010 Management Shell, SharePoint 2010 Central Administration, or SharePoint Designer.

SharePoint Community Search by Lawrence Liu

Lawrence Liu recently posted his Live Search macro enabling a consolidated search against the SharePoint Community; to add to that capacity I’ve put together a small bookmarklet that will enable you to run this search from your browser without having to navigate away from your current page.


Download
https://wbaer.officeisp.net/Shared%20Documents/SharePoint_Community_Search_Bookmarklet.zip

Recycle Bin for SharePoint Products and Technologies 2003 (WSS/SPS 2003) 1.2 (Build 29) Released!

Recycle Bin 1.2 (Build 29) has been released; this release addresses several issues reported in build 26, released in July.  Currently this build is offered as independent libraries and will soon have an accompanying Windows Insaller Package.  To install this build, stop the World Wide Web Publishing Service (NET STOP W3SVC), replace ReycleBinISAPI.dll and RecycleBinISAPIFilter.dll with build 29 and start the World Wide Web Publishing Service (NET START W3SVC).  Download Recycle Bin 1.2 (Build 29).


Additional Details:


For this latest build we’ve only modified the ArchiveSTRMN function in RecycleBinHandlerRecycleBin.cs; if you’ve customized the source code to suit your environment I’ve attached the changes:

  /// <summary>
///
/// </summary>
/// <param name=”context”></param>
/// <param name=”sNow”></param>
/// <param name=”sLogonUser”></param>
private void ArchiveSTRMN(HttpContext context, string sNow, string sLogonUser)
{
Libs.Utils.WriteLog(Libs.Utils.Level.Level5, “Enter ArchiveSTRMN:”);
try
{
string sReturn = “”;
// get the OrigUrl from the query string
// get the item being deleted from the request form “cbx”
// sCbx=[url;;doclib95/2004-09-07-001.sql;File,url;;doclib95/folder01/c++ check list.sql;File]
string sCbxes = context.Request.Form[“cbx”];
string sOrigUrl = context.Request.QueryString[“OrigUrl”];

bool useHttps = (context.Request.ServerVariables[“HTTPS”].ToLower() == “on”)? true:false;

// what do we need to use – http or https?
string uriScheme = useHttps ? “https://” : “http://”;

if(context.Request.Form[“do_delete”].ToLower() == “true” && sCbxes != null)
{
Libs.Utils.WriteLog(Libs.Utils.Level.Level7, “* In ArchiveSTRMN:rn . sCbxes=[“, sCbxes ,“]rn . sOrigUrl=[“, sOrigUrl ,“]”);
string sSiteUrl = “”;
ArrayList alCbxes = SplitByString(sCbxes, “url;”);
string[] asCbx = null;
string sSubSiteUrlFromSite = “”;
string sItemUrlFromSite = “”;
string sItemUrl = “”;
SPWeb spWeb = null;
SPList spList = null;
for (int i=0; i<alCbxes.Count && sReturn == “”; i++)
{
if ((string)alCbxes[i] == “”)
{
continue;
}
sSiteUrl = sOrigUrl.Replace(“_layouts/1033/storman.aspx”, “”);
asCbx = ((string)alCbxes[i]).Split(“;”.ToCharArray(), 1000);
sSubSiteUrlFromSite = asCbx[0];
sItemUrlFromSite = asCbx[1];
Libs.Utils.WriteLog(Libs.Utils.Level.Level7, “* In ArchiveSTRMN:rn . sSiteUrl=[“, sSiteUrl ,“]rn . sSubSiteUrlFromSite=[“, sSubSiteUrlFromSite ,“]rn . sItemUrlFromSite=[“, sItemUrlFromSite ,“]”);
sItemUrl = Libs.SharePointLib.MakeUrl(uriScheme + context.Request.ServerVariables[“SERVER_NAME”].ToLower(), sSiteUrl);

sItemUrl = Libs.SharePointLib.MakeUrl(sItemUrl, sSubSiteUrlFromSite);
sItemUrl = Libs.SharePointLib.MakeUrl(sItemUrl, sItemUrlFromSite);

spWeb = Libs.SharePointLib.GetSPWeb(sItemUrl, ref sSiteUrl, ref sReturn, sLogonUser);
spList = null;
switch (GetSPObjectType(spWeb, sItemUrlFromSite, sSiteUrl, ref spList))
{
case SPObjectType.SPListItem:
if ((sReturn=Libs.SharePointLib.CopyListItemUseUrl(sItemUrl, sRecycleFolder, sLogonUser)) == “”)
{
if ((sReturn=Libs.SharePointLib.DeleteListItemUseUrl(sItemUrl, sLogonUser)) != “”)
{
Libs.Utils.WriteLog(Libs.Utils.Level.Level1, “*** In ArchiveSTRMN: DELETE – sReturn=[“ + sReturn + “]”);
Libs.Utils.WriteAppLog(EventLogEntryType.Error, “*** In ArchiveSTRMN: DELETE – sReturn=[“ + sReturn + “]”);
// context.Response.Redirect (ERROR_PAGE_URL + MSG_TO_USER, false);
context.Response.Redirect (ERROR_PAGE_URL + sReturn, false);
}
else
{
WriteActionLog(sNow, “,”, System.Environment.MachineName, “,”, sItemUrl, “,”, sLogonUser);
}
}
else
{
Libs.Utils.WriteLog(Libs.Utils.Level.Level1, “*** In ArchiveSTRMN: DELETE – sReturn=[“ + sReturn + “]”);
Libs.Utils.WriteAppLog(EventLogEntryType.Error, “*** In ArchiveSTRMN: DELETE – sReturn=[“ + sReturn + “]”);
// context.Response.Redirect (ERROR_PAGE_URL + MSG_TO_USER, false);
context.Response.Redirect (ERROR_PAGE_URL + sReturn, false);
}
break;

case SPObjectType.SPDocumentLibrary:
ArrayList alFileUrls = new ArrayList();
if ((sReturn=Libs.SharePointLib.CopyDocLibUseUrl(sItemUrl, sItemUrlFromSite, sRecycleFolder, ref alFileUrls, sLogonUser)) == “”)
{
if ((sReturn=Libs.SharePointLib.DeleteDocLibUseUrl(sItemUrl, sItemUrlFromSite, sLogonUser)) != “”)
{
Libs.Utils.WriteLog(Libs.Utils.Level.Level1, “*** In ArchiveSTRMN: remove documents – sReturn=[“ + sReturn + “]”);
Libs.Utils.WriteAppLog(EventLogEntryType.Error, “*** In ArchiveSTRMN: remove documents – sReturn=[“ + sReturn + “]”);
// context.Response.Redirect (ERROR_PAGE_URL + MSG_TO_USER, false);
context.Response.Redirect (ERROR_PAGE_URL + sReturn, false);
}
else
{
WriteActionLog(sNow, “,”, System.Environment.MachineName, “,”, sItemUrl, “,”, sLogonUser);
}
}
else
{
Libs.Utils.WriteLog(Libs.Utils.Level.Level1, “*** In ArchiveSTRMN: DELETE – sReturn=[“ + sReturn + “]”);
Libs.Utils.WriteAppLog(EventLogEntryType.Error, “*** In ArchiveSTRMN: DELETE – sReturn=[“ + sReturn + “]”);
// context.Response.Redirect (ERROR_PAGE_URL + MSG_TO_USER, false);
context.Response.Redirect (ERROR_PAGE_URL + sReturn, false);
}
break;

case SPObjectType.SPSpecialList:
if ((sReturn = CopyListUseUrl(spList, sRecycleFolder, sLogonUser))==“”)
{
try
{
Libs.Utils.WriteLog(Libs.Utils.Level.Level7, “* In ArchiveSTRMN: Deleting spList.Title=[“, spList.Title ,“] spList.ID=[“, spList.ID ,“]”);
spList.Lists.Delete(spList.ID);
WriteActionLog(sNow, “,”, System.Environment.MachineName, “,”, sItemUrl, “,”, sLogonUser);
}
catch (Exception oE)
{
if(oE.Message.ToLower().IndexOf(“security validation”) > -1 || oE.Message.ToLower().IndexOf(“acccess is denied”) > -1)
{
context.Response.Redirect (ERROR_PAGE_URL + “The folder selected for deletion contains one or more lists, document libraries, or galleries that your Web site requires in order to function correctly. Therefore, you cannot delete the folder.”, false);
}
else
{
Libs.Utils.WriteLog(Libs.Utils.Level.Level1, “*** In ArchiveSTRMN: DELETErn . Message=[“ + oE.Message + “]rn . ToString=[“ + oE + “]”);
Libs.Utils.WriteAppLog(EventLogEntryType.Error, “*** In ArchiveSTRMN: DELETE:rn .Error=[“ + oE + “]”);
context.Response.Redirect (ERROR_PAGE_URL + oE.Message.Replace(“r”, ” “).Replace(“n”,” “), false);
}
}
}
else
{
Libs.Utils.WriteLog(Libs.Utils.Level.Level1, “*** In ArchiveSTRMN: DELETErn . Error=[“ + sReturn + “]”);
Libs.Utils.WriteAppLog(EventLogEntryType.Error, “*** In ArchiveSTRMN: DELETE:rn .Error=[“ + sReturn + “]”);
context.Response.Redirect (ERROR_PAGE_URL + sReturn.Replace(“r”, ” “).Replace(“n”,” “), false);
}
break;
case SPObjectType.SPNone:
// sReturn = “Unsupported the deletion of [” + sItemUrl + “]”;
// Libs.Utils.WriteLog(Libs.Utils.Level.Level1, “*** In ArchiveSTRMN: DELETE:rn . sReturn [“, sReturn, “]”);
// Libs.Utils.WriteAppLog(EventLogEntryType.Error, “*** In ArchiveSTRMN: DELETErn . sReturn=[” + sReturn + “]”);
break;
}
}
// copy over the item or items
// delete the item or items
// now make the request
}
// Now make a request to the actual storman.aspx page ONLY if the action complete successfully
if (sReturn == “”)
{
string serverName = uriScheme + context.Request.ServerVariables[“SERVER_NAME”].ToLower();

Libs.Utils.WriteLog(Libs.Utils.Level.Level7, “* In ArchiveSTRMN:rn . ServerName=[“ + serverName + “]rn . useHttps=[“ + useHttps.ToString() + “]”);

System.Net.HttpWebRequest req = (HttpWebRequest)WebRequest.Create(serverName + sOrigUrl + “?bypass=1”);
req.Method = “POST”;
req.KeepAlive = true;
req.ContentType = “application/x-www-form-urlencoded”;
req.Credentials = CredentialCache.DefaultCredentials;

Stream st = req.GetRequestStream();
StreamWriter w = new StreamWriter(st);

// make sure we don’t ask the actual storman.aspx to delete
w.Write (context.Request.Form.ToString().Replace(“do_delete=true”, “do_delete=false”));

st.Close();

// get the response from actual storman
System.Net.HttpWebResponse resp = (System.Net.HttpWebResponse)req.GetResponse();

st = resp.GetResponseStream();

StreamReader r = new StreamReader(st);

string res = r.ReadToEnd().Replace(“<!– delete disabled on system file –>”, “<input type=”hidden” id=”lbl_0″ name=”lbl” value=”” /><input type=”checkbox” value=”” disabled id=”cbx_2″name=”cbx” />”);

//bug #19 and #20
res = res.Replace(uriScheme + context.Server.MachineName.ToLower() + “/”, uriScheme + context.Request.ServerVariables[“SERVER_NAME”].ToLower() + “/”);

// remove the bypass stuff from the body of response and also the url header
context.Response.Write (res.Replace(“?bypass=1”, “”));
context.Response.AddHeader(“url”, uriScheme + context.Request.ServerVariables[“SERVER_NAME”].ToLower() + sOrigUrl);
}
}
catch(Exception oE)
{
Libs.Utils.WriteLog(Libs.Utils.Level.Level1, “*** In ArchiveSTRMN:rn . Error=[“, oE, “]”);
Libs.Utils.WriteAppLog(EventLogEntryType.Error, “*** In ArchiveSTRMN:rn . Error=[“, oE, “]”);
// context.Response.Redirect (ERROR_PAGE_URL + MSG_TO_USER, false);
context.Response.Redirect (ERROR_PAGE_URL + oE.Message, false);
// context.Response.Write (x.Message);
}

context.Response.Flush();
// context.Response.End();
Libs.Utils.WriteLog(Libs.Utils.Level.Level5, “Exit ArchiveSTRMN:”);
}

Recycle Bin for SharePoint Products and Technologies 2003 (WSS/SPS 2003) 1.2 (Build 26) Released!

I’ve published Recycle Bin 1.2 (Build 26) to SharePoint Tools GotDotNet Workspace, this build addresses two long-standing bugs:



Fixes Explorer View bug:

Unable to delete <file>

An error occurred accessing your FrontPage web files. Please contact the server administrator.

Fixes Empty Library archiving:

Document and Picture Libraries that do not contain content will be archived in effort to mirror the directory structure of a Document/Picture Library and its’ subfolders if they exist.


Download the latest release at:  http://www.gotdotnet.com/workspaces/releases/viewuploads.aspx?id=8437a203-f377-401c-b23d-ae59e6f05b80 we are very interested in your comments on this latest release.

Web Services, XSL and Windows SharePoint Services Content Management *UPDATED

I recently posted an article detailing how the Content Editor Web Part can be leveraged to display a menu based on the SELECT element, using hypertext markup and javascript to render hyperlinks in a manner that maximizes Windows SharePoint Services real-estate and promotes a positive user experience. Several requests and questions I received as a result of this post were whether or not the hyperlinks in the Content Editor Web Part could be harvested from a List. As a result I’ve put together this, albeit, brief tutorial. In this article you will create a Windows SharePoint Services List, create a new XSL transform Data View Web Part, connect to the Lists Web Service, and specify Exensible Style Language (XSL) and JavaScript (JS) to both render, populate and handle to form content.

Create a Windows SharePoint Services ‘Custom’ List

1. Open a Windows SharePoint Services site in your browser, this site will host the List providing the Web Part its content.

2. Select Documents and Lists from the top navigation bar.

3. Click Create, and then select Custom List under Custom Lists.

4. Enter a name and optional description for the list in the Name: and Description: text boxes and click OK.

5. Select Modify settings and columns on the left navigation bar.

6. Select Add a new column under Columns.

7. Enter URL for the new column name in the Column name: text box and click OK.  Accept the default values when creating the new column.

8. Go back to the list and add at least two new items.  The Title should be the textual representation for your link.

Connect to the Windows SharePoint Services Lists Web Service

1. Open the List in Microsoft Office FrontPage 2003 or a Windows SharePoint Services compatible Web page editor.

2. Select an open area of the page to insert the Data View.

NOTE The following instructions are specific to Microsoft Office FrontPage 2003, consult your Web page editor for instructions corresponding to the remaining instructions.

3. Select Data, and then select Insert Data View.

4. Select Add to catalog… under XML Web Services from the Data Source Catalog dialog.

5. In the Data Source Properties window enter the location for the Lists Web Service in the Service description location box and click Connect Now.  The Lists Web Service is typically located at http://<portal>/<site>/_vti_bin/Lists.asmx?WSDL.

6. Select ListsSoap and GetListItems in the Port: and Operation: menus.

7. Double-click the listName Name in the Parameters(*required) dialog.

8. Enter the name of the List that contains the content for the Web Part in the Value: box and click OK.

9. Click OK on the Data Source Properties window.

10. Click the Web Service from the Data Source Catalog dialog and then select Insert Data View from the menu.

11. Remove the ows_Attachements, ows_Title, and ows_ID columns from the Data View.

12. Select Data from the Microsoft Office FrontPage 2003 taskbar, and then select Style…. from the menu.

13. Select the dropdown HTML view from the list of available views in the View Styles window and click OK.  Click Yes if presented with a formatting warning dialog.

Edit the XSL Transform Data View Web Part Source Code

1. Click Code on the Microsoft Office FrontPage 2003 page view options menu.

2. Locate the line <select name=”ID” size=”1″> and replace with <select name=”spjump” onchange=”window.open(this.options[this.selectedIndex].value)”>.

3. Enter the JavaScript below above the line <select name=”spjump” onchange=”window.open(this.options[this.selectedIndex].value)”>.


<!–

–>function menu_spjump(path) {

window.open = path.options[path.selectedIndex].value;

}

//–>


NOTE You can optionally replace the text Choose One… in the line <option selected=”true” value=”0″>Choose One…</option> to suit your needs, this is the default dropmenu option visible in the Web Part.

4. Locate the line <option style=”display:{$GroupStyle}”> and replace with <option>.

5. Enter the following XSL attributes below the line <option>.

<xsl:attribute name=”value”>

<xsl:value-of select=”@ows_URL”/>

</xsl:attribute>

6. Save the page.

Refresh the Windows SharePoint Services List


  1. Open the Windows SharePoint Services list in your browser.  Your XSL Data View will be visible below the standard List view.

Additional Options

If you would like to use the dropdown menu on another area of your site or install the menu as a Web Part elsewhere in your SharePoint environment, repeat the steps in the section Connect to the Windows SharePoint Services Lists Web Service; however, prior to step 3, select Data, and the select Web Part Zone from the menu in Microsoft Office FrontPage 2003, then proceed to with the remaining steps.  This option will create a Web Part in which the dropdown menu will be hosted.  You can export the Web Part from the Lists page in Windows SharePoint Services and uploaded the Web Part to other sites in your SharePoint environment on elsewhere on your site. The dropdown menu will show content added to your list.  If you would like to leverage the OPTGROUP element, simply create an additional column in your List labeled OPTGROUP and call the values in the XSL stylesheet for the List.

If you have any questions on how to implement steps in this tutorial or require troubleshooting assistance, please comment below.