Integrating a Custom ASP.NET Application into SharePoint (Part 2)
Posted by DevExpert on February 25th, 2009
In my last post, I began describing how to integrate a custom ASP.NET application into SharePoint. SharePoint is a fantastic platform for building applications, and being able to create your own pages and application structure is a huge win when you need to add missing functionality, or to integrate a non-SharePoint application into SharePoint.
My previous post covered the basics – where to place your custom artifacts, how to inherit the master page and navigation, and how the custom application runs in the context specified in the URL. This post will briefly cover securing your application pages and will also cover some useful design and UI techniques to give your application a truly integrated look and feel.
If you took at a look at the code I provided, you may have noticed that my custom base class that sets the master page is inheriting from LayoutsPageBase. This is a page in the object model that is specifically meant to be inherited, and provides us the means to check the users’ rights. Since Natnael Gebremariam of Bamboo Solutions already did a fantastic job of explaining this and some of the nuances in his post here, I will skip that and just provide a high-level overview. Basically there are 3 properties that can be overridden to customize the required permissions for your page:
- AllowAnonymousAccess: A boolean value indicating if the page is accessible by anonymous users.
- RequireSiteAdministrator: A boolean value indicating if the page is only accessible by site collection administrators.
- RightsRequired: A list of SPBasePermissions that specify the granular permissions that are necessary to access the page.
For the purposes of this blog series I kept it simple, and I’m denying anonymous access, not requiring users to be site collection administrators, but requiring the user to have at least ManageLists and ManageWeb permissions:
protected override bool AllowAnonymousAccess { get { return false; } } protected override bool RequireSiteAdministrator { get { // only allow site collection administrators access? return false; } } protected override SPBasePermissions RightsRequired { get { SPBasePermissions permissions = base.RightsRequired | SPBasePermissions.ManageLists | SPBasePermissions.ManageWeb; return permissions; } }
What I don’t particularly like is only being able to specify the permissions that are available through SharePoint, and not being able to specify my own. What if I wanted to check against Active Directory, or the users’ presence in a group, or validate against a line-of-business application? It’s not built-in, but Natnael describes a pretty good approach that will allow you to accomplish this.
Alright, now that I have the security in place, I can begin building the application. I’m going to pretend this application is a front-end to a line-of-business database that manages my Widget inventory. The focus of the rest of this post is going to be on utilizing some out-of-the-box SharePoint web controls. Don’t pay too much attention to the implementation of these, as this will serve as an overview of some of the server and user controls that you can leverage. In future posts I’ll elaborate a little on some of these and provide the nitty-gritty details, but for the sake of brevity I’ll just be covering the basics here.
First, we need to register the controls that we are going to use at the top of the ASPX pages. This is not a comprehensive list, but should give you the idea:
<%@ Register TagPrefix="wssuc" TagName="InputFormSection" Src="/_controltemplates/InputFormSection.ascx" %> <%@ Register TagPrefix="wssuc" TagName="InputFormControl" Src="/_controltemplates/InputFormControl.ascx" %> <%@ Register TagPrefix="wssuc" TagName="ButtonSection" Src="/_controltemplates/ButtonSection.ascx" %> <%@ Register TagPrefix="wssuc" TagName="ToolBar" Src="/_controltemplates/ToolBar.ascx" %> <%@ Register TagPrefix="wssuc" TagName="ToolBarButton" Src="/_controltemplates/ToolBarButton.ascx" %> <%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
Toolbar/SPToolBarButton
Many applications have a need for a toolbar, and even SharePoint is littered with them. You’re able to build one of your own by using the Toolbar.ascx user control (inside the CONTROLTEMPLATES folder), and the SPToolBarButton controls (found within the Microsoft.SharePoint.WebControls namespace):
<wssuc:Toolbar id="tb" runat="server"> <Template_Buttons> <SharePoint:SPToolBarButton ID="btnAdd" runat="server" Text="Add Widget" ImageUrl="Images/add.gif" NavigateUrl="AddWidget.aspx" /> <SharePoint:SPToolBarButton ID="btnRefresh" runat="server" Text="Refresh List" ImageUrl="Images/refresh1.ico" OnClick="btnRefresh_Click" /> </Template_Buttons> <Template_RightButtons> <SharePoint:SPToolBarButton ID="btnHelp" runat="server" Text="Help" ImageUrl="Images/help.gif" NavigateUrl="Help.aspx" /> </Template_RightButtons> </wssuc:Toolbar>
The above markup will render:
SPGridView
The next control worth mentioning is the all-powerful SPGridView control. This control is inherited from the ASP.NET GridView control which is already a great control, but the SPGridView provides a ton more functionality. In supports grouping, it automatically inherits the styles of SharePoint, and you are able to add drop-down menus to your items, like users are already used to in lists and libraries. The markup syntax is pretty straightforward:
<SharePoint:SPGridView ID="grid" runat="server" AutoGenerateColumns="false" AllowSorting="true" AllowGrouping="true" GroupField="Category" AllowGroupCollapse="true"> <Columns> <asp:BoundField HeaderText="ID" DataField="ID" SortExpression="ID" /> <asp:BoundField HeaderText="Name" DataField="Name" SortExpression="Name" /> <asp:BoundField HeaderText="Price" DataField="Price" SortExpression="Price" /> <asp:BoundField HeaderText="Quantity on Hand" DataField="QuantityOnHand" SortExpression="QuantityOnHand" /> <asp:BoundField HeaderText="Date Added" DataField="DateAdded" SortExpression="DateAdded" /> </Columns> </SharePoint:SPGridView>
The above markup will render
Let’s take this a step further and add the familiar drop-down list to the Name column. There are a ton of examples on how to do this in code-behind, most notably Powlo’s posts here and here, but here’s a little preview on how to do this in the markup. First, we need to create our MenuTemplate, which defines the items in the drop-down list:
<SharePoint:MenuTemplate ID="menuTemplate" runat="server"> <SharePoint:MenuItemTemplate ID="menuEdit" runat="server" Text="Edit Widget" ImageUrl="Images/gear.gif" ClientOnClickScript="javascript:editSomething('%ID%');" /> <SharePoint:MenuItemTemplate ID="menuDelete" runat="server" Text="Delete Widget" ImageUrl="Images/delete.gif" ClientOnClickScript="javascript:deleteSomething('%ID%');" /> </SharePoint:MenuTemplate>
Next, replace the BoundField with an SPMenuField, and specify the menu this is bound to by assigning the MenuTemplateID property to the ID of the menu template we just created. The TokenNameAndValueFields property assigns a token to a field in the data source. In this example, I’m declaring two tokens, one for ID and another for Name, which can then be used elsewhere. The NavigateUrlFields specifies the fields that can be used in the URL set in the NavigateUrlFormat property, and in the same order (it works like the String.Format() method):
<SharePoint:SPMenuField HeaderText="Name" TextFields="Name" MenuTemplateId="menuTemplate" TokenNameAndValueFields="ID=ID,NAME=Name" NavigateUrlFields="ID" NavigateUrlFormat="EditWidget.aspx?id={0}" />
The above markup will render:
Form Fields
For creating form fields, there are a ton of ways to skin this cat, but I typically choose one of the following two approaches. Typically your data-entry forms should either look like the forms used for new list items, or the forms for new lists, sites, or pages. The simplest and arguably cleanest approach is to just use the ASP.NET controls you’re used to, such as a TextBox, DropDownList, etc., and place them in a table that have the SharePoint styles applied to them. The end result will look something like this:
The markup is pretty simple; the important part is is the style classes applied to the elements, specifically ms-formlabel, ms-formbody, and ms-input. For the sake of brevity, here is a portion of the markup for the above form:
<tr> <td class="ms-formlabel"> Date Added: </td> <td class="ms-formbody"> <asp:TextBox id="txtDateAdded" runat="server" CssClass="ms-input" width="200px" /> </td> </tr> <tr> <td class="ms-formlabel"> Category: </td> <td class="ms-formbody"> <asp:DropDownList id="txtCategory" runat="server" CssClass="ms-input" width="200px"> <asp:ListItem>Cheap Widgets</asp:ListItem> <asp:ListItem>Expensive Widgets</asp:ListItem> </asp:DropDownList> </td> </tr>
The second approach is to make the form look like the new list/site pages in SharePoint. This is perfectly fine too, but takes up a little more space:
The markup for this is a little more complex, and involves the use of InputFormSection and InputFormControl sections. A sample of the markup used for the above form is as follows:
<wssuc:InputFormSection runat="server" Title="" id="dateSection"> <template_description> <b>Date</b><br />Please specify a date. </template_description> <template_inputformcontrols> <wssuc:InputFormControl runat="server" LabelText="Date:"> <Template_Control> <wssawc:DateTimeControl ID="txtDate" runat="server" DateOnly="true" /><BR /> </Template_Control> </wssuc:InputFormControl> </template_inputformcontrols> </wssuc:InputFormSection> <wssuc:InputFormSection runat="server" Title="" id="categorySection"> <template_description> <b>Category</b><br />Please specify a category </template_description> <template_inputformcontrols> <wssuc:InputFormControl runat="server" LabelText="Category:"> <Template_Control> <wssawc:InputFormTextBox ID="txtCategory" runat="server" Columns="40" class="ms-input" /><BR /> </Template_Control> </wssuc:InputFormControl> </template_inputformcontrols> </wssuc:InputFormSection> <wssuc:ButtonSection runat="server" ShowStandardCancelButton="false"> <Template_Buttons> <asp:Button runat="server" class="ms-ButtonHeightWidth" Text="Save" id="btnSave" /> <asp:Button runat="server" class="ms-ButtonHeightWidth" Text="Cancel" id="btnCancel" CausesValidation="false" /> </Template_Buttons> </wssuc:ButtonSection>
As you can see, it’s lot more code, but you’re given a few extra things to work with, like the label and label description to the left, and the extra space to the right. You’ll also notice I’m using built-in SharePoint controls for the textboxes and the date picker. There are a bunch of controls that you can leverage, many of which I’ll cover in a future post. If you’re ambitious though, feel free to poke around the assembly with Reflector or the Object Browser in Visual Studio. Here’s a screenshot of what you’ll find:
There’s all kinds of goodies that are available for us to use in our applications. Stay tuned for a future post that will dive into a few more of them!
February 26th, 2009 at 9:29 am
Wow! Thanks for such great content. I wish Microsoft would hire you to work on their documentation
.
One question – Those GIFs that you have in the toolbar and the little dropdown, are those part of the images provided by SharePoint? If not, where did you get them? I could
easily make use of those.
February 26th, 2009 at 9:30 am
Ooops, there were was another question.
Can the little dropdowns be controlled by security (only show for folks with certain
security)?
February 26th, 2009 at 1:46 pm
Lance,
Thanks for the great feedback! Keep checking back — I plan on having a bunch more content just like this!
To answer your first question, no, those images aren’t provided by SharePoint. I’m accumulated quite a collection of icons and images like that over the years from web sites, applications, etc. A great place to look for images like that is IconLook or IconFinder.
As far as controlling the menu items with security, you can absolutely do that too. Check out the PermissionsString property and the Permissions property of the MenuItemTemplate control.
Hope this helps!
February 27th, 2009 at 9:10 am
Great Job and thanks for the post!
March 24th, 2009 at 10:42 am
I keep getting a
“Value does not fall within the expected range.” error when I run my page with the Toolbar implementation.
When I look into my .aspx page, it is telling me
“Runtime error: Fail to map path ‘/_controltemplates/ButtonSection.ascx’”
I copy pasted the code but the files are in place so.. help
Apart from that, great stuff, keep it up
March 24th, 2009 at 6:49 pm
Jimmy,
It’s hard to troubleshoot without looking at your environment, but I would double-check that the ButtonSection.ascx actually exists in the CONTROLTEMPLATES folder within the 12 directory. Also, where are you deploying your .ASPX files to? Let me know and I’ll try to help!
April 30th, 2009 at 3:09 pm
Thanks for this great info. I am developing a custom application integrated with Share Point site. I am using the approach using Table and ASP.net controls, but using the ms-formbody etc Share Point styles. But I would like to use the DateTime Control Share Point has (text box and the small calendar button), can you tell us how to use that control as I could not find any direct ascx file for that control.
Thanks.
June 2nd, 2009 at 10:11 am
Hello,
can you explain a bit more how do you deploy this ?
can you provide the copy.bat scripts?
thx
June 2nd, 2009 at 10:17 am
Shpop, if you take a look at the first post in this series, you’ll see how/where to deploy all custom files. Unfortunately I don’t have the copy.bat scripts anymore.
June 3rd, 2009 at 2:05 am
Great!
Last question for you
is there a way to debug this correctly?
I was thinking to do everything outside sharepoint and the deploy but elements such SPMenuField requires SPContext :S so I really need to deploy it everytime I want to test it?
thx in advance
June 17th, 2009 at 4:03 pm
I want to get a similar functionality in a DataForm Web Part. Is it possible. Could you provide me some info about that.
June 25th, 2009 at 2:21 pm
Rahul,
I’m not sure what specific functionality you’re referring to. Can you elaborate a little more? I’m not sure I’ll be able to help, as most of this stuff is specific to creating pages and/or custom web parts.
June 25th, 2009 at 2:26 pm
Shpop,
You can definitely develop everything outside of SharePoint, but if you want to debug it (by “debug” it I’m assuming you mean attach the debugger and step through code), you will have to develop and deploy your solution on the SharePoint server itself, or by setting up remote debugging (which I’ve never been able to get working properly). If you develop directly on the server, you can simply attach to the w3wp.exe process and step through your code without a hitch.
July 22nd, 2009 at 6:08 pm
Sucheta – the DateTimeControl is part of the Sharepoint.WebControls namespace. You can change the tag from wssawc to Sharepoint (since it should already registered on top of your page). See this URL for more information: http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.webcontrols.aspx
July 22nd, 2009 at 7:02 pm
I’m just loving this… Thank you for the information!!!
July 28th, 2009 at 10:53 am
Question on security trimming the drop down menu options.
I tried the PermissionsString and Permissions properties but they don’t seem to work. I have a custom SPGridView on the sites home page that is populated by a query. I don’t think my grid knows the ‘context’ of the permissions since the items in the grid are just rows from a datatable?
It seems like the permission context is the web site, not the individual items in the grid. Any ideas?
August 15th, 2009 at 9:45 am
Steve, the PermissionsString and Permissions properties respect the permissions that are present on the site from which your page was accessed, and has nothing to do with what’s in the database. If the current user doesn’t have the appropriate permissions that are specified on the SharePoint site, then those menu options won’t appear. Does this make sense?
August 17th, 2009 at 3:11 pm
Thanks for the response,
I agree the PermissionsString and Permissions properties are based on the site permissions for that user – at least that’s what’s happening for me.
What I was hoping to do though is trim the drop down options based on the actual item the drop down is related to – not the site. So the user may have Contribute access to the site, but the actual item has unique permissions and they may only have Read access to the item itself. So I don’t want the user to see the “Delete” drop down option for items they don’t have permission to delete.
August 17th, 2009 at 3:41 pm
Steve, unfortunately those properties check the site permissions, and cannot be configured to check a custom source. My suggestion would be to declare those menu items programmatically in the code-behind (instead of in the HTML markup), and do your permission checking there. It’s probably more work to do it that way, but is probably the only way to do what you’re suggesting.
Check out this post — it goes into how to do create menus and menu items for the SPGridView programmatically. Good luck!
September 21st, 2009 at 12:12 am
Now that you have created the forms and all how do we connect them to a list is there some auto binding or database?
November 6th, 2009 at 2:13 am
Hi
Suggest me what is the best way to deploy asp.net web site on MOSS2007
February 2nd, 2010 at 1:53 am
wonderful post.
April 12th, 2010 at 2:25 pm
I just found this site a while ago when a buddy of mine recommended it to me. I’ve been an avid reader ever since.
May 19th, 2010 at 3:23 am
DevExpert – great series of articles. I have a small custom application that I am looking to implement in SP that needs to integrate with a specific SP List to manage the display view and data entry. The Display page needs to have some custom Search logic available and the Data Entry screen for the List needs to have enhanced validation and field level permissions assigned. For these reasons, I thought I would need to develop 2 different custom ASP pages. I was going to do this myself but am now looking to outsource the design and development. Any interest?
December 17th, 2010 at 10:31 am
The article is excellent. Please
consider having a paid login may be using paypal, and allow us to download code which will help us save lots of time and would add more detailed clarity to finer points.