Tuesday, 27 January 2009

Steps to Create a Alert WebControl and deploy to MOSS

After many days I got an opportunity to create a webcontrol which creates the Alerts for the Logged in user. As my client insisted that they dont want to strain users by navigating inside the Sharepoint application page to create a alert, they want to create an alert with a single mouse click.


Steps involved in creating a webcontrol:
1) Create a button control,intialize it on the Page load, Assign the click event to that
And attach code for that event handler.

Code goes like this.


namespace AlertMeWC
{

[ToolboxData("<{0}:ManageAlerts runat=server>")]
public class ManageAlerts : WebControl
{


private System.String btnCreateAlert;
private LinkButton btnCreate;

public System.String btnCreateAlertID
{
get
{
return btnCreateAlert;
}
set
{
btnCreateAlert = value;
}
}

private void CreateAlert(object sender, EventArgs e)
{

try
{
SPSecurity.RunWithElevatedPrivileges(delegate(){

SPSite _site = SPContext.Current.Site;
SPWeb _web = _site.OpenWeb();
SPAlert newalert = _web.Alerts.Add();
newalert.AlertType = SPAlertType.Item;
newalert.AlertFrequency = SPAlertFrequency.Immediate;
newalert.DynamicRecipient = Get the Logged in user details.

if (HttpContext.Current.Request.Url.ToString().ToLower().Contains("/pages"))
{
newalert.Item = _web.GetListItem(HttpContext.Current.Request.Url.ToString()); newalert.Title = "Pages: FirstPage.aspx";
newalert.Update();
_web.AllowUnsafeUpdates = true;
_web.Update();
_web.AllowUnsafeUpdates = false;
}
});
}
catch (Exception ex)
{
Page.Response.Write("Error in ManageAlerts " + ex.Message.ToString());
}
finally
{
//Dispose web
}
}

private void InitializeControls()
{
btnCreate = InitializeControls("btnCreateAlert", btnCreateAlert);
}

private T InitializeControls(string strPropertyName, string strControlID)
{
object _BaseControl = null;
T _Return = default(T);

if (String.IsNullOrEmpty(strControlID))
{
throw new ApplicationException("ManageAlerts Initialization failed: The " + strPropertyName + " attribute must specify a valid " + typeof(T).ToString() + ". The attribute was not specified.");
}

_BaseControl = this.NamingContainer.FindControl(strControlID);

if (_BaseControl == null)
{
throw new ApplicationException("ManageAlerts Initialization failed: The " + strPropertyName + " attribute must specify a valid " + typeof(T).ToString() + ". The control " + strControlID + " cannot be found.");
}

if (!(_BaseControl is T))
{
throw new ApplicationException("ManageAlerts Initialization failed: The " + strPropertyName + " attribute must specify a valid " + typeof(T).ToString() + ". The control " + strControlID + " is a " + _BaseControl.GetType().ToString() + ", and is not supported.");
}

_Return =(T)_BaseControl;
Return _Return;
}

protected override void OnLoad(EventArgs e)
{

base.OnLoad(e);
try
{
InitializeControls();

btnCreate.Click += new EventHandler(this.CreateAlert);

}
catch (Exception ex)
{
Page.Response.Write("Error: " + ex.Message.ToString());
}
finally
{
}

}


}
}


2)Assign the strong name, GAC and grab public key token.
3)Navigate to your site where we would like to stick this webcontrol on.
4)Create a new page and edit that page in Sharepoint designer.
Add the following lines to that Page in SPD.
<@ Register Tagprefix="muki" Namespace="AlertMeWC" Assembly="AlertmeWC, Version=1.0.0.0, Culture=neutral, PublicKeyToken=#$@$%@$%@#%@5" %>
Add this in body tag.
<muki:ManageAlerts ID="ManageAlerts" runat="server" btnCreateReportID ="btnCreate"/>

When ever the user clicks on this link, then automatically alerts are created
Enjoy SPD'ing!!

Monday, 15 December 2008

Adding Site Collection Administrators programatically

One of my team mates had a question whether we can add site collection Administrators to the site through object model.
Its fairly simple and easy.
code chunks:
****************************************************************************
SPSite _site = null;
SPUser user = null;
SPWeb _web = null;
try
{

SPSecurity.RunWithElevatedPrivileges(delegate()
{

_site = new SPSite("siteURL");

_web = _site.OpenWeb();
_web.AllowUnsafeUpdates = true;
_web.SiteUsers.Add(@"mossbox\user1", "user1@email.com", "user1", "Added via object model");
_web.Update();
user = _web.SiteUsers[@"mossbox\user1"];
_site.SecondaryContact = user;
user.Update();
_web.AllowUnsafeUpdates = false;
});
}
catch (Exception ex)
{

MessageBox.Show("Error in Adding Site Collection Administrators " + ex.Message.ToString());


}
finally
{
if (_site != null)
{
_site.Dispose();
}
if (_web != null)
{
_web.Dispose();
}

}


}

****************************************************************************

Thursday, 28 August 2008

Host ASP.NET UserControls in MOSS

I got an interesting change request from my client manager, where they want to host the ASP.NET user control as is in MOSS(This has DLL available). I googled around and found five different ways to do and one mukiway(my way)
1. Deploy the Usercontrol using Smart Part
2. Wrap the UserControl with webpart
3. Modify the UserControl as Webcontrol and deploy the control
4. Recreate this UserControl as new Webpart
5. Deploy this control into 12 hive controltemplates folder along with .cs file

Mukiway:
1. Copy the control and its files into _Layouts/MukiControl/
2. Create a test page in ASP.NET and host the UserControl in that test page
<% Register src="UserControl.ascx" tagname="mukicontrol" tagprefix="muki" %>
In the body tag
<muki:UserControl ID="UserControl" runat="server"/>
save this page as test.aspx

3. GAC the UserControl DLL
3. Mark that DLL as safe entry in web.config file of the hosting site collection
4. Perform IISReset.
5. Add a PageViewer Webpart
6. Select Web Page as option and in the URL field give /_Layouts/MukiControl/test.aspx

Cheers! you are done.

Friday, 15 August 2008

Prevent users from viewing Application Pages

As a part of security measure, we have been asked to restrict the people accessing the default application pages like /Forms/Allitems.aspx,/_layouts/mcontent.aspx, Userdisp.aspx.
I ve heard about viewlockdownfeature but also heard that there are some issues with that. So I thought we can do this task by a custom http handler.
In order to make this handler configurable instead of hardcoding the URL's I made an entry in node of web.config file and redirect those URL's to desired page.
The code for Http Handler goes like this :

******************************************************************
// Description:
// This HTTP handler redirects the Application pages to desired page defined in <AppSettings>node in web.config file
//
// Implementation :
//<httpModules>
//<add name="ReRoutePages" type="muki.ReRouteAppPages, ForceSSL,Version=1.0.0.0, Culture=neutral,PublicKeyToken=XXXXX" />
//</httpModules>
//<appsettings>
//<add key ="ApplicationPages" value="/Forms/AllItems.aspx,/_layouts/settings.aspx"/>
//<add key ="AdminPagesReRoutedURL" value ="http://servername/Pages/DontSeethosePages.aspx"/>
//</appsettings>

*******Code begins***********************
namespace muki
{
class ReRouteAppPages : System.Web.IHttpModule
{
#region IHttpModule Members

public void Dispose()
{
throw new NotImplementedException();
}

public void Init(System.Web.HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}

#endregion
void context_BeginRequest(object sender, EventArgs e)
{
ReRoutePages(System.Web.HttpContext.Current.Request.Url.PathAndQuery);
}
public void ReRoutePages(string pageURL)
{
//check for the current page exists in the group of pages requiring ReRouting
//if page is found in ReRoute group then redirect page to desired page as per web.config entry
try
{
bool found = false;
string AppPages = System.Configuration.ConfigurationSettings.AppSettings["ApplicationPages"];
string destURL = System.Configuration.ConfigurationSettings.AppSettings["AdminPagesReRoutedURL"];
char[] separator;
separator = new char[] { ',' };
string[] pages;
pages = AppPages.Split(separator);

for (int i = 0; i < pages.Length; i++)
{
if (pageURL.ToLower().Contains(pages[i].ToLower()))
{
found = true;
break;
}
}
if (found)
{
HttpContext.Current.Response.Redirect(destURL);
}

}
catch (Exception ex)
{

HttpContext.Current.Response.Write("An error has occured in ReRouting Application Pages" + ex.InnerException.ToString());
}

}
}
}

******************************************************************

2.Strong Name the assembly and GAC it.
3.Refer the Implementation
4.Perform IISReset.

We are done right!