in

SharePoint Blogs

The Best Place for SharePoint-related Blogs

Sam's Blog

  • Developing a reusable SQL Data viewer WebPart for Sharepoint -Part 3

    Customize the webpart properties for dynamic connection to SQL server and to enable paging in Grid view.

    In Part 2 of the post, we looked at how to execute a SQL statement against a database and display the result in the web part as a gridview. Before going to Part 3 of developing a reusable SQL Data viewer web part for Sharepoint, please follow the steps in Part II. 

    In Part III of the post, we will enhance this web part and add properties to the web part so that connection to SQL Server and the SQL statement can be configured after the webpart is added to the page. We will also throw in an eventhandler for the gridview to handle paging. If you have lots of records, we want them to show in pages. We will also look at how to configure the page size through properties.


    Note: The example below shows how to save configuration data in properties in plain text.If you feel such a method is not suitable for your security needs, you should find a way to use encryption on the data being saved in the properties and a method to decrypt that when accessing from code. 


    We will first create a webpart property called ServerName and also a method called ServerName

    See Code Listing Below


    public class DataViewer : WebPart

    {


            private string servername;

            [Personalizable(), WebBrowsable(true),

            WebDisplayName("ServerName"), Category("Data Properties")]

            public string ServerName

            {

                get { return servername; }

                set { servername = value; }

            }


    In the above code, we declared a private data member called servername and a get,set method called ServerName


    We also created a webpart property called “ServerName” which will be displayed in a section called “Data Properties”


    We will now create some more properties, see code listing below

     

        public class DataViewer : WebPart

        {

            private string servername;

            [Personalizable(), WebBrowsable(true),

            WebDisplayName("ServerName"), Category("Data Properties")]

            public string ServerName

            {

                get { return servername; }

                set { servername = value; }

            }

            private string dbname;

            [Personalizable(), WebBrowsable(true),

            WebDisplayName("DatabaseName"), Category("Data Properties")]

            public string DatabaseName

            {

                get { return dbname; }

                set { dbname = value; }

            }

            private string username;

            [Personalizable(), WebBrowsable(true),

            WebDisplayName("UserName"), Category("Data Properties")]

            public string UserName

            {

                get { return username; }

                set { username = value; }

            }

            private string password;

            [Personalizable(), WebBrowsable(true),

            WebDisplayName("Password"), Category("Data Properties")]

            public string Password

            {

                get { return password; }

                set { password = value; }

            }

            private string innerpassword;

            [Personalizable(), WebBrowsable(false),

            WebDisplayName("InnerPassword"), Category("Data Properties")]

            public string InnerPassword

            {

                get { return innerpassword; }

                set { innerpassword = value; }

            }

            private string sqlquery;

            [Personalizable(), WebBrowsable(true),

            WebDisplayName("SQLQuery"), Category("Data Properties")]

            public string SQLQuery

            {

                get { return sqlquery; }

                set { sqlquery = value; }

            }

            private int datarows;

            [Personalizable(), WebBrowsable(true),

            WebDisplayName("RowsPerPage"), Category("Data Properties")]

            public int DataRows

            {

                get { return datarows; }

                set { datarows = value; }

            }


    All the properties are similar in declaration accept for a property called “InnerPassword”. You will notice that the WebBrowsable property for innerpassword is set to false.  This property will not be visible to users and it is created so that the password can be stored internally in this property.


    Build the project by clicking on Build>>Build Dataviewer


    Once you have successfully build the assembly, go to the sharepoint site where the dataviewer webpart was originally added and refresh the page.

    Modify the dataviewer webpart properties and you will see a section called “Data Properties” as shown below

     

    The “Data Properties” section havs 6 text boxes.

    ·         Server Name = [name of the SQL Server]

    ·         DatabaseName= Name of the Database

    ·         UserName= SQL server login account

    ·         Password = SQL Server Password

    ·         SQLQuery= T-SQL Statement to query the database

    ·         RowsPerPage = number of rows to be displayed in the gridview for a page


    In the next section, we will now add code to capture the values entered in these properties and then execute it in the webpart.


    We will modify the CreateChildMethods and instead of using static SQL Strings or connections, we will read the connection and sql statement from the properties.


    The following codes have been added

    if (password != "******")

    {

         InnerPassword = password;

         password = "******";

    }


    string strConnection = "UID=" + username + ";PWD=" + innerpassword + ";Initial Catalog=" + dbname + ";Data Source=" + servername + ";";

                       

    string sql = sqlquery;

    objDB.StrConnection = strConnection;

    DataTable dt = new DataTable();

    dt = objDB.GetSQlResult(sql);


    Let’s examine the code above. If the password ( this is the password property) is not equal to “******” then we will assign the password to Innerpassword and set the password to “******”


    The reason for doing this is, if someone entered a SQL Server password on the webpart, we do not want to show the password to the user again, instead we will show “******” to prevent other people from accessing the password of SQL server by looking at the properties.


    In the next line, we are building the SQL server connection string by reading the properties of the web part.

    In the sql string we get the value from the sqlquery property of the webpart.


    We are now dynamically reading the SQL connection string and the query from the webpart properties, next step is just execute the GetResult method of our DBAccess object and bind the datatable returned to the gridview.


    We will now add code to enable paging in the gridview. We also need to specify the page size. We will set the allowpaging property of gridview to true and also add an eventhandler to enable paging for gridview. The pagesize will be assigned from the “datarows” properties.

     

    gv.AllowPaging = true;

    gv.PageSize = datarows;

    gv.PageIndexChanging += new GridViewPageEventHandler(this.gv_PageIndexChanging);


    We will need to manually create the method for the event handler as below


    protected void gv_PageIndexChanging(object sender, GridViewPageEventArgs e)

           

    {

          gv.PageIndex = e.NewPageIndex;

          string strConnection = "UID=" + username + ";PWD=" + innerpassword + ";Initial Catalog=" + dbname + ";Data Source=" +    servername + ";";

         

          DbAccess objdb = new DbAccess();

          objdb.StrConnection = strConnection;

          DataTable dt = objdb.GetSQlResult(sqlquery);

          gv.DataSource = dt;

          gv.DataBind();

    }


    Note: The gridview should not be instantiated inside the CreateChildControls Method anymore because the gv_PageIndexChanging will not be able to access the object, we will therefore instantiate the gridview as a member of the class.


      public class DataViewer : WebPart

        {

            GridView gv = new GridView();


    Build the project. Go to the sharepoint page where the webpart has been added previously. Refresh the page.When the webpart reloads you may see an error message. This is expected because the database connections and SQL query has not been set.


     

     

    You will now need to edit the dataview webpart properties to make the error go away and execute your SQL Statement.


    Change the Title to : Employees

    Expand the Dataproperties section and enter your connection information


     

     

    Once the properties have been entered, click “Apply” and then click “OK”. You will now see that the web part displays the result of your sql query.

    Important: The RowsPerPage must have a number greater than 0.

    When the page loads, the page should similar to this, base on your data and your SQL Statement


      

     


    You can now add more dataviewer webparts on the page and connect it to different SQL Servers or run different SQL Statements.  Example below

     

    You can now build a report dashboard based on this dataviewer webpart and re-using it multiple times on the same page by simply configuring the connection and query properties.

  • Developing a reusable SQL Data viewer WebPart for Sharepoint - Part II

    Create the Data Access library and display query results in GridView

    This is the Part II of the 3 Parts on how to create a reusable SQL Data VIewer Web Part. If you missed Part I, here is the link. Part I

    In the part I of the post, we looked at how to create a simple webpart and deploy it to the bin directory. The webpart simply displayed a static text. We will now look at changing the webpart code and overriding some base class method so that instead of a static text, it will display data from SQL server database in a grid view.

    In the part I of the post, we started a project called dataviewer, we will now continue with the same project.

    Add a new class to the project and call it DBAccess

    In the using section add the namespace

    using System.Data.SqlClient;

    The DBAccess.cs should look like this

     

     

    We are now going to add some methods to the class DBAccess

    Add a private data member called strConnection of string type. This will hold the connection information to the sql server database from where the query result will be fetched.

    Create a get, set method for this data member so that we can set the connection string property through the assessors. Code snippet is shown below

    public class DbAccess

        {

            private string strConnection;

            public DbAccess()

            {

            }

            public string StrConnection

            {

                get { return strConnection; }

                set { strConnection = value; }

            }

      }

    We need to create a method called GetSQLResult which returns a data table and takes a SQL statement as a parameter

    public DataTable GetSQlResult(string sql)

            {

                DataTable dt = new DataTable();

                try

                {

                    SqlConnection cnn = new SqlConnection(strConnection);

                    SqlDataAdapter da = new SqlDataAdapter(sql, cnn);

                    da.Fill(dt);

                    return dt;

                }

                catch (Exception ex)

                {

                    return dt;

                }

            }

    Build the project again. If the build fails, make sure all the namespaces are included. The namespaces required for this class are

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.Data.SqlClient;

    using System.Data;

    After adding references, build the project again, make sure there are no errors.

    You have successfully created the data access library.

    Next step is to, use this DAL ( data access library) on the web part  and display the data in a grid view.

    Open the dataviewer.cs code file, we will now look at the method to display the output on a webpart. The method that displayed the output is shown below

    protected override void RenderContents(HtmlTextWriter output)

    {

          output.Write("Data Viewer Test");

    }

    This is a base class method and we chose to override it in our class. The output is a HtmlTextWriter which gets displayed in the webpart UI.

    We can also choose to override another base class method which will produce the same result, the method is called createchildcontrols.

    See code listing below

    protected override void CreateChildControls()

    {

               base.CreateChildControls();

    }

    If we are going to create controls like gridview, labels,textboxes etc and display it in webpart, it is much better to override the createchildcontrols method because it is easier to manage the order in which the user controls will be displayed in the webpart. We will therefore choose to override the createchildcontrols instead of  rendercontents method

    The next step is to create a gridview control and then bind the gridview to a datatable. We will then add the gridview to the controls collection so that the gridview will be displayed in the webpart with the result of the sql statement.

    See code listing below

     

    In the above listing, I have commented the RenderContents method because I want to use the CreateChildControls method to display the gridview in the webpart.

    The strConnection string has the connection information to the sql server.

    UID: name of the sql server account,

    PWD: password for the user, I

    nitial Catalog: Database to which you want to connect and finally

    Data Source: The name of the server in which the SQL Server is running.

    If you have multiple SQL Servers running on this machine, you have to specify the instance name as well Example: testserver\SQLEngine1

    Build the project, Build>>Build Data Viewer

    If there are any build errors. Make sure that you have followed the code listings and included the namespaces correctly.

    Go back to the sharepoint site on which you had added the DataViewer webpart in Part I of the blog. Simply refresh the page and you will now see that the web part loads with a gridview and a result of the SQL Statement.

    See Screenshot below:

     

    You have now successfully created a webpart that takes a SQL Statement, database connection string and executes the SQL statement and displays the result in the web part.

    In part I, we set the assembly version to 1.0.0.0 and this makes it easy to test our changes by simply refreshing or reloading the page that contains the webpart. If we had not set the assembly to a fixed version, everytime we build our dataviewer project, it would create a new revision number and you would be required to edit the web.config and register the control as safe.

    The problem with the above webpart is that the SQL statement and the connection information to the server are stored in the assembly.

    In part III of the “Developing a reusable SQL Data viewer WebPart for Sharepoint”, we will look at how to store the SQL statement and connection string in the webpart properties, so that it can be configured easily. We will also look at how to set paging properties of the gridview.

      

  • Is Moss 2007 a platform or a solution?

     I think MOSS is both a platform and a solution. I am going to broadly categorize some of the capabilities of MOSS 2007 into two buckets and then explain my rationale for why a specific capability is in a particular bucket

     

    Solution
    •  Web Content Management/portals
    • Enterprise Search
    Platform
    •  Business Intelligence using Excel Services
    •  Business Process using InfoPath Forms
    Solution:  If you are planning to implement a new corporate intranet with portal capability, you will use the publishing template along with MySites. The out of box capability can get you far enough that you will probably focus only on specific items like branding, configuring the site structure, security, content and some minor customization. The OOB capability of sharepoint can meet most of your needs for a corporate search engine. You may be able to get this up and running in a relatively short time by configuring the search, scopes and content sources. I think that sharepoint is a solution for WCM and Enterprise search because it addresses most of the business need with the out of box functionality. The WCM and search investment in sharepoint can be realized fairly quickly by just configuring the out of box features. You have a quicker time to deploy an intranet site or a search engine and your focus is mostly on content.  

     

    Platform: If you are planning to implement a business intelligence solution or form based application you will use BDC, excel services and InfoPath form services. These are however pieces of the pie. Excel services and report center templates by itself cannot provide you business intelligence. It provides the framework and the presentation layer for your underlying data.Even before you get to using sharepoint for business intelligence, You will need to start out by understanding the data structure in a LOB applications, figure out a way to get to the data by either designing an OLAP solution or consume web services or directly connecting the data source through providers. You will then need to publish connection strings to secure connection library and then start developing the reports using excel 2007. You can develop your excel reports to sharepoint and then present the report in a dashboard. When you get this far, most of pieces are together and you are now addressing the business intelligence requirement.  For business intelligence, we use the sharepoint infrastructure for the purpose of application security layer (control access, permission), presentation layer (dash board, navigation, content, excel services web part) and report design tool (Excel 2007). 

     

    If you are planning to implement a web based expense entry with reports, you will need to use InfoPath form services, work flows etc. Infopath will provide you the design tool to start developing the forms but most of the time applications are much more than a form. You will need workflows, notifications and reports on data entered into the forms. In some cases, you may need to integrate the expenses into a project management system or other applications. Here again, Infopath form services is one piece of the pie. In the above two context, sharepoint is a platform for business intelligence and form based applications. You choose the infrastructure and the framework provided by sharepoint to ultimately achieve your business needs.

     

     I can see that sharepoint BDC and excel services are a good solution for building dashboards and reporting portals. Using excel as a reporting design tool seems to be a very smart move since most of the business users are familiar with excel and it also empowers the end users to build their own reports based on data connections quite easily. How many times have you built reports that have changed 10 times because the requirements kept changing? Well, with excel services, developers can now focus on the OLAP, data connections and all the useful things whereas the report power users can focus on creating reports that suits their needs. I am not sure I can say the same thing about InfoPath Form Services. While, InfoPath makes it easy to design forms and quickly deploy it, is it a good platform for applications? Is InfoPath a good option to actually develop complex applications based on the fact that it has an easy designer and can be deployed into sharepoint.  Are we constrained by the functionality of the form designer? As a developer, I still need to play around with InfoPath a lot more before I can make an assessment, but for now, I am more comfortable developing business applications using visual studio and .net. I welcome any experience or ideas from readers who have used InfoPath forms services extensively.

     

    Posted Oct 20 2007, 06:57 PM by sam with 3 comment(s)
    Filed under:
  • How to restrict public access to sharepoint list views using filters

    In sharepoint you can either create a personal or a public view on a document libraries, lists etc. You may come across situations where you need only a few individuals to see a particular view.

    Lets take an example

     Your have a custom list containing software contract information like customer, license type, product, contract date,contract currency, contract amount etc. You are required to allow everyone in the sales department to see this list however the contract amount should be visible only to few management executives. You may create 2 public views, one that has the contract amount and the other that does not. The next step would be to provide read-access to the list to all the people in the sales department.

    In sharepoint, if you give read access to a list or library, the person will also have read access to all public views. which means, by default everyone is able to see both the views, one with the contract amount and the one without. Not being able to control access on views seems to be a design flaw/gap in sharepoint. I hope Microsoft will address this in the next release or a service pack. Until that time, here is a workaround that may work in some of the cases

    On the list where you want to restrict access to views to a few individual:

    • Create a column called "Restricted users".
    • Column Type = Person or Group
    • Allow Multiple Selections =Yes
    • Allow Selection of = People Only
    • Choose From = All Users (This is the list of Users from your Active Directory(
    • Show Field= Name ( Choose this from the drop down)

    Lets say John Smith and Jane Smith are 2 executives who need to see the list views with the contract amount

    Open up the list in data sheet view.  [List Name]>>Actions>> Edit In Datasheet

    Scroll to the column called "Restricted Users"

    Under the column, in the first cell type John Smith;Jane Smith  ( These 2 names should be in AD exactly as spelled, if not find the correct spelling)

    Copy this cell to the rest of the cells under the "restricted users" column and save.

    Create a view for this contract list, call it "Contract-Restricted"  or an appropriate name. This view should be created as a public view.

    In the filter section where it says "show the items when"

    • Choose "Restricted Users" from the dropdown list
    • Condition =Is equal to
    • In the text box type [Me]

    When sales people login to the site and selects the list, they will see both the views but when they choose the "Contract-Restricted" view, they will not see any results because of the filter.

    The filter essentially looks at the current user logged in sharepoint, if it is John Smith or Jane Smith, the filter condition is met and it returns the result in the "contract-restricted" view otherwise the view will not return any result.

     

     

  • Restore a production sharepoint web farm to a new web farm

     If you have a production WSS 3.0 sharepoint environment and need to copy the production data into a test environment web farm (different web farm), it can be done using SQL backups and restore.

    I am more comfortable using this method than using stsadm tool. This could also be helpful when your production system crashes and you need to quickly get a backup sharepoint farm up and running with the latest production data.

    Note: Make sure that you have a database maintenance plan, that backs up your production content databases nightly.

     Production sharepoint farm steps
     
     • In SQL Server Enterprise Manager, back up all Windows SharePoint Services 3.0 databases.
     
     
     Target farm steps ( if you are setting up a brand new WSS 3.0 farm)
     
    1.  Install Windows SharePoint Services 3.0 on the target farm computer. Do not create a web application.
     
    2.  In SQL Server Enterprise Manager, restore to the target farm computer, all Windows SharePoint Services 3.0 databases except the configuration database and the central administrator content database. Use the Restore Databases menu option.
     
    3.  In the Windows SharePoint Services 3.0 central administrator console, create a web application for the portal site. If you have more web applications in the source farm, create the corresponding web applications in the target farm.
     
    4.  In the Windows SharePoint Services 3.0 central administrator console, detach the content database from the newly created web application by doing the following:

    5.  From the Application Management page click the Content Databases link under the SharePoint Web Application Management section.
     
    6.  Change the web application from the drop down list.
     
    7.  Select the content database.
     
    8.  Select Offline for Database Status and check the remove content database
     
    9.  Click OK.
      
    10.  Attach the restored site Content database for the newly created web application.

    11. On the Application Management page click Content Databases under SharePoint Web Application Management.
     
    12.  Change the web application from the drop down list
     
    13.  Click Add a content database.
     
    14.  Enter the SQL Server name and the name of the restored database.
     
    15.  Click OK.
      
    16.  Start the search crawl from the Search Setting page.
     
    17.  Click OK on the pop up dialog to resume the crawl.

    You have now created a brand new web farm that is a copy of the production web farm.


    Target farm steps (if WSS 3.0 farm is already Installed  and has web applications)
     

    1. Make sure that you have same number of web application on this target server as the production server. You will need to use this web application for the restore of the production web application.
     
    2.  Go to  Windows SharePoint Services 3.0 central administrator console, select the web application from the web application list.

    3.  Select the content database.
     
    4.  Select Offline for Database Status and check the remove content database
     
    5.  Click OK.

    6. Go to the SQL Server and delete the content database

    7. Create an empty database on the SQL server and name it the same as the content database that you want to restore from the production web farm

    8. Restore the backup taken from the production on this empty database.

    9. Go back to Central Administration site
    10 On the Application Management page click Content Databases under SharePoint Web Application Management.
    11.  Change the web application from the drop down list
    12.  Click Add a content database.
    13.  Enter the SQL Server name and the name of the restored database.
    14.  Click OK.
    15.  Start the search crawl from the Search Setting page.
    16.  Click OK on the pop up dialog to resume the crawl.

    You should now have a copy of the production web farm in a test environment.


Need SharePoint Training? Attend a SharePoint Bootcamp!

Posts (c) their respective authors. Everything else (c) 2007 SharePoint Experts