DevExpertise » Blog Archive » Integrating a Custom ASP.NET Application into SharePoint (Part 2)

DevExpertise

Practical tips and tricks for all things .NET, SharePoint, Silverlight, InfoPath, and general application development.

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:

image 

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

image

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:

image 


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:

image

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:

image

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:

image

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!

25 Responses to “Integrating a Custom ASP.NET Application into SharePoint (Part 2)”

  1. Lance Says:

    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.

  2. Lance Says:

    Ooops, there were was another question.

    Can the little dropdowns be controlled by security (only show for folks with certain
    security)?

  3. DevExpert Says:

    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!

  4. Rick Says:

    Great Job and thanks for the post!

  5. Jimmy Says:

    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

  6. DevExpert Says:

    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!

  7. Sucheta Says:

    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.

  8. Shpop Says:

    Hello,

    can you explain a bit more how do you deploy this ?

    can you provide the copy.bat scripts?

    thx

  9. DevExpert Says:

    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.

  10. Shpop Says:

    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

  11. rahul Says:

    I want to get a similar functionality in a DataForm Web Part. Is it possible. Could you provide me some info about that.

  12. DevExpert Says:

    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.

  13. DevExpert Says:

    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.

  14. Clarence Says:

    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

  15. Clarence Says:

    I’m just loving this… Thank you for the information!!!

  16. Steve Says:

    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?

  17. DevExpert Says:

    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?

  18. Steve Says:

    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.

  19. DevExpert Says:

    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!

  20. samir Says:

    Now that you have created the forms and all how do we connect them to a list is there some auto binding or database?

  21. Neeraj Says:

    Hi
    Suggest me what is the best way to deploy asp.net web site on MOSS2007

  22. Mahmoud Says:

    wonderful post.

  23. Joe Nici Says:

    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.

  24. Don Says:

    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?

  25. Chinna Says:

    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.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>