Creating a Visual Web Part in Visual Studio for SharePoint 2010

I started classes at SetFocus (http://www.setfocus.com/) several months back to continue improving my skill set as a developer. I am always trying to discover new innovative ways to develop and understand new development strategies. I wanted to share this one with everyone since I thought it was somewhat difficult to implement at first but very simple and elaborate when complete.

I started with a empty SharePoint project and then added a Visual Web Part to the project. One thing you have to have is a SharePoint on the machine that you are using the Visual Studio to view and use the SharePoint project software. However SharePoint 2010 and Visual Studio 2010  has come along ways compared to previous versions. The functionality and ability has increased and the simplicity for developers like me (must be simple for little brains like mine) is really awesome.

The first thing you need to do is open Visual Studio 2010 on the machine that you have the SharePoint installed on.

Then select File\New Project ==> Then Choose Empty SharePoint Project.

I named my Empty SharePoint Project: CreateSolutionSiteWebPart. Then add to that project a Visual Web Part.

By selecting the Empty SharePoint Project and right clicking and selecting Add ==> New Item you will get a add new item list box. Select the Visual Web Part.

Once the Visual Web Part is added to the SharePoint Project you will see it is really nothing more then a .ascx user control. So you can add a div tag on the source view of the .ascx page. This is an example of the code I added to that form.

<div>

    <asp:Label ID="lblSiteName" Text="Site Name: " runat="server" Width="100" />
    <asp:TextBox ID="txtSiteName" runat="server" />

    <asp:Label ID="lblSiteDescription" Text="Site Description: " runat="server" />
    <asp:TextBox ID="txtSiteDescription" runat="server" />

    <asp:Label ID="lblIntendedURL" Text="Intended URL: " runat="server" />
    <asp:TextBox ID="txtIntendedURL" runat="server" />

    <asp:Label ID="lblSiteTemplate" Text="Site Template: " runat="server" />
    <asp:DropDownList ID="ddlSiteTemplate" runat="server"
        onselectedindexchanged="ddlSiteTemplate_SelectedIndexChanged">
    </asp:DropDownList>

    <asp:CheckBox ID="chkUniquePermissions" Text="Unique Permissions " runat="server" />

    <asp:Button ID="btnSubmit" runat="server" onclick="btnSubmit_Click"
        Text="Submit" />

</div>

Next I created the code behind that is required for the application. That looks like this.

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Collections;
using System.Collections.Generic;

namespace CreateSolutionSiteWebPart.CreateSolutionSiteWP
{

    public partial class CreateSolutionSiteUC : UserControl
    {
        SPWebTemplateCollection wt;

        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            if (txtSiteName.Text == string.Empty && txtIntendedURL.Text == string.Empty)
                return;

            using (SPSite site = new SPSite(@"http://URLName:PortNumber/sites/Solutions"))
            {
                using (SPWeb web = site.RootWeb)
                {
                    try
                    {

                        SPSecurity.RunWithElevatedPrivileges(() => web.Webs.Add(
                            txtIntendedURL.Text,
                            txtSiteName.Text,
                            txtSiteDescription.Text,
                            1033,
                            ddlSiteTemplate.SelectedValue,
                            chkUniquePermissions.Checked,
                            false));

                        ScriptManager.RegisterClientScriptBlock(this, this.GetType(), Guid.NewGuid().ToString(), "alert('Success');", true);

                    }
                    catch (Exception ex)
                    {
                        string error = ex.Message;
                        ScriptManager.RegisterClientScriptBlock(this, this.GetType(), Guid.NewGuid().ToString(), "alert('" + error + "');", true);

                    }
                    finally
                    {
                        txtSiteName.Text = string.Empty;
                        txtSiteDescription.Text = string.Empty;
                        txtIntendedURL.Text = string.Empty;
                    }
                }
            }

        }

        protected override void OnLoad(EventArgs e)
        {

            EnsureChildControls();

            if (!IsPostBack)
            {
                using (SPSite site = new SPSite(@"http://URLName:PortNumber/sites/Solutions"))
                {
                    using (SPWeb web = site.RootWeb)
                    {
                        try
                        {
                            wt = web.GetAvailableWebTemplates(1033);
                            foreach (SPWebTemplate template in wt)
                            {
                                ddlSiteTemplate.Items.Add(new ListItem(template.Title, template.Name));
                            }
                            ddlSiteTemplate.DataBind();

                        }
                        catch (Exception ex)
                        {
                            string error = ex.Message;
                            ScriptManager.RegisterClientScriptBlock(this, this.GetType(), Guid.NewGuid().ToString(), "alert('" + error + "');", true);
                        }
                    }
                }
            }

        }

    }
}

I removed the real URL and Port Number for security however all the other code is exact.

This code gives the ability to add a Visual Web Part to your SharePoint 2010 that will allow for a user with permissions to create a new site on the SharePoint Portal. This is really not that amazing but it does show the simplicity and power of what Visual Studio 2010 and SharePoint 2010 is capable of doing. I am very impressed with the functionality and collaboration that can be accomplished is a very small amount of time.

This is an example of the simple look and feel of the Visual Web Part on the web site.



    	
    	

Again thanks to Pluralsite video and the suggestion from Keith Brown of Pluralsite

After my last post Keith Brown had made the suggestion to:

“You might try factoring the test into a SPECIFICATION (google the specification pattern for more). Very simple refactoring but then you’ll be able to use your tests not just for validation, but also for selection and build-to-order objects. Glad you’re enjoying the library!”

Which I thought was a great suggestion, however I am not a real programmer… So I turned to Pluralsite to help me to become a real programmer. I am posting this but I am not sure of the validity of this yet.

Any constructive criticism is greatly appreciated.

I decided to try to re-factor my test into a specification pattern. Here is my attempt:

I first developed the Interface IValidation<TEntity>:

namespace BusinessRules
{
    public interface IValidation<TEntity>
    {
        bool IsSatisfiedBy(TEntity entity);
    }
}

I then created three concrete classes that implemented the above interface.

Those classes were the classes I thought would be my validation rules that needed to be checked which are:

using System;

namespace BusinessRules
{
    public class EmployeeNameIsValid : IValidation<Employee>
    {
        public bool IsSatisfiedBy(Employee employee)
        {
            if (employee != null)
            {
                if (!String.IsNullOrEmpty(employee.Name))
                {
                    return true;
                }
                return false;
            }
            return false;
        }
    }
}
namespace BusinessRules
{
    public class EmployeeIdIsValid : IValidation<Employee>
    {
        public bool IsSatisfiedBy(Employee employee)
        {
            if (employee != null)
            {
                if (employee.EmployeeID > 0)
                {
                    return true;
                }
                return false;
            }
            return false;
        }
    }
}
namespace BusinessRules
{
    public class EmployeeDepartmentIdIsValid : IValidation<Employee>
    {

        public bool IsSatisfiedBy(Employee employee)
        {
            if (employee != null)
            {
                if (employee.DepartmentID > 0)
                {
                    return true;
                }
                return false;
            }
            return false;
        }
    }
}

I then Thanks to Wikipedia discovered this explanation of the pattern.  http://en.wikipedia.org/wiki/Specification_pattern. So I used there example to develop a group of extension methods for testing the And, Or and Not validation chaining.

I created the chaining functionality by creating the And, Or and Not as an extension methods like this:

namespace BusinessRules
{
    public class AndValidation<TEntity> : IValidation<TEntity>
    {
        private IValidation<TEntity> _validation1;
        private IValidation<TEntity> _validation2;

        public AndValidation(IValidation<TEntity> v1, IValidation<TEntity> v2)
        {
             _validation1 = v1;
             _validation2 = v2;
        }

        public bool IsSatisfiedBy(TEntity entity)
        {
            return _validation1.IsSatisfiedBy(entity) && _validation2.IsSatisfiedBy(entity);
        }
    }
}
namespace BusinessRules
{
    public class OrValidation<TEntity> : IValidation<TEntity>
    {
        private IValidation<TEntity> _validation1;
        private IValidation<TEntity> _validation2;

        public OrValidation(IValidation<TEntity> v1, IValidation<TEntity> v2)
        {
            _validation1 = v1;
            _validation2 = v2;
        }

        public bool IsSatisfiedBy(TEntity entity)
        {
            return _validation1.IsSatisfiedBy(entity) || _validation2.IsSatisfiedBy(entity);
        }
    }
}
namespace BusinessRules
{
    public class NotValidation<TEntity> : IValidation<TEntity>
    {
        private IValidation<TEntity> _validation1;

        public NotValidation(IValidation<TEntity> v1)
        {
            _validation1 = v1;
        }

        public bool IsSatisfiedBy(TEntity entity)
        {
            return !_validation1.IsSatisfiedBy(entity);
        }
    }
}
namespace BusinessRules
{
    public static class ExtensionMethods
    {
        public static IValidation<TEntity> AndValidation<TEntity>(this IValidation<TEntity> v1, IValidation<TEntity> v2)
        {
            return new AndValidation<TEntity>(v1, v2);
        }

        public static IValidation<TEntity> OrValidation<TEntity>(this IValidation<TEntity> v1, IValidation<TEntity> v2)
        {
            return new OrValidation<TEntity>(v1, v2);
        }

        public static IValidation<TEntity> NotValidation<TEntity>(this IValidation<TEntity> v1)
        {
            return new NotValidation<TEntity>(v1);
        }
    }
}

From there is was trying to figure out how to put it all together to have the functionality of the previous post. I re-factored the program class that I originally developed to try to improve on that functionality like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BusinessRules
{
    class Program
    {
        public static void Main(string[] args)
        {
            string error = EmployeeRules();
            Console.WriteLine(error);
            Console.ReadKey();
        }

        private static string EmployeeRules()
        {

            var employeeIdIsValid = new EmployeeIdIsValid();
            var employeeDepartmentIdIsValid = new EmployeeDepartmentIdIsValid();
            var employeeNameIsValid = new EmployeeNameIsValid();

            var rules = new List<Rule<Employee>>()
                            {

                                new Rule<Employee>()
                                    {
                                        Test = employeeNameIsValid.IsSatisfiedBy,
                                        Message = "name cannot be empty"
                                    },

                                new Rule<Employee>()
                                    {
                                        Test = employeeIdIsValid.IsSatisfiedBy,
                                        Message = "must have an employeeID"
                                    },

                                new Rule<Employee>()
                                    {
                                        Test = employeeDepartmentIdIsValid.IsSatisfiedBy,
                                        Message = "must have an assigned department"
                                    }

                            };

            StringBuilder stringBuilder = new StringBuilder();
            foreach (var employee in Employee.GetEmployee())
            {
                if (employee != null)
                {
                    var test = employeeNameIsValid.AndValidation(employeeIdIsValid).AndValidation(employeeDepartmentIdIsValid);
                    var isValid = test.IsSatisfiedBy(employee);

                    if (!isValid)
                    {
                        var failedRules = rules.Where(r => r.Test(employee) == false);

                        string errorMessage =
                            failedRules.Aggregate(new StringBuilder(),
                                                  (sb, r) => sb.AppendLine(r.Message),
                                                  sb => sb.ToString());
                        return stringBuilder.ToString() + Environment.NewLine + String.Format("Error: {0} is Invalid \r\n Employee {1}: {2} ", employee.Name, employee.Name, errorMessage);
                    }
                }

                if (employee != null) stringBuilder.Append(String.Format("Employee: {0} Is Valid \r\n", employee.Name));
            }
            return stringBuilder.ToString();
        }

    }
}

Again I am not sure of the validation of this code being a true “specification pattern”.

I want to thank Keith Brown for the suggestion and Wikipedia for the great example of the code to help me try to find the way to being a good developer!!

BusinessRules using LINQ

After watching the Pluralsite video on LINQ from Scott Allen. I wanted to implement a example that would help me understand some of the functionality that I saw. I was really impressed with the implementation of the Business Rules that Scott did with the LINQ aggregate function. So I developed a small console application that used some of this technology. I first developed a small Rules class like the video shows:

using System;

namespace BusinessRules
{
    public class Rule<T>
    {
        public Func<T, bool> Test { get; set; }
        public string Message { get; set; }
    }
}

This is a small generic class that exposes two properties. This first property is a Func<T, TResult> delegate. Which MSDN states a Func<T, TResult>: Encapsulates a method that has one parameter and returns a value of the type specified by the TResult parameter. And the second property is the message that will be used for the validation.

I then created a small employee class that will be my data to test in the validation rules.

This is very simple class like this:

using System.Collections.Generic;
using System.Linq;

namespace BusinessRules
{
    public class Employee
    {
        #region Properties

        public int EmployeeID { get; set; }
        public string Name { get; set; }
        public int DepartmentID { get; set; }

        #endregion

        #region Constructor
        public Employee()
        {
            //Used for AutoImplementation
        }

        public static List<Employee> GetEmployee()
        {
           var employee =  new List<Employee>
                                {
                                    new Employee() { EmployeeID = 1, Name = "Allan", DepartmentID = 1 },
                                    new Employee() { EmployeeID = 2, Name = "Quincy", DepartmentID = 2},
                                    new Employee() { EmployeeID = 3, Name = "Bella", DepartmentID = 2},
                                    new Employee() { EmployeeID = 0, Name = "Rylee", DepartmentID = 3}
                                }.ToList();

            return employee;

        }
        #endregion

        #region Methods()
        public override string ToString()
        {
            return string.Format("Employee: EmployeeID = {0}, Name = {1}, DepartmentID = {2}", EmployeeID, Name,
                                 DepartmentID);
        }
        #endregion

    }
}

Finally I created a small EmployeeRules() method that would be used to validate the business rules.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BusinessRules
{
    class Program
    {
        public static void Main(string[] args)
        {
            string error = EmployeeRules();
            Console.WriteLine(error);
            Console.ReadKey();
        }

        private static string EmployeeRules()
        {
            var rules = new List<Rule<Employee>>()
                            {
                                new Rule<Employee>(){ Test = e => !String.IsNullOrEmpty(e.Name),
                                    Message = "name cannot be empty"},

                                new Rule<Employee>() {Test = e => e.DepartmentID > 0,
                                    Message = "must have an assigned department"},

                                new Rule<Employee>() {Test = e => e.EmployeeID > 0,
                                    Message = "must have an employeeID"}
                            };

            StringBuilder stringBuilder = new StringBuilder();
            foreach (var employee in Employee.GetEmployee())
            {
                if (employee != null)
                {
                    bool isValid = rules.All(r => r.Test(employee));

                    if (!isValid)
                    {
                        var failedRules = rules.Where(r => r.Test(employee) == false);

                        string errorMessage =
                            failedRules.Aggregate(new StringBuilder(),
                                                  (sb, r) => sb.AppendLine(r.Message),
                                                  sb => sb.ToString());
                        return stringBuilder.ToString() + Environment.NewLine + String.Format("Error: {0} is Invalid \r\n Employee {1}: {2} ", employee.Name, employee.Name, errorMessage);
                    }
                }

                stringBuilder.Append(String.Format("Employee: {0} Is Valid \r\n", employee.Name));
                //return stringBuilder.ToString();
            }
            return stringBuilder.ToString();
        }

    }
}

This functionality seems to be very simple and straight forward to even me and I am not very smart. I was impressed by the simplicity that Scott Allen showed with his video and yet still showed the true power of LINQ in one example.

Thanks to Scott Allen and http://www.pluralsight-training.net for the examples and functionality.

NetTryx CRM is up and running!

NetTryx LLC. has now implemented a solution for a Customer Relations Management Software solution for Evaluation. I am really excited to announce that it is the SplendidCRM Community Edition. I am going to be developing some additional functionality as the weeks progress. This is a very cool ASP.net open source solution to SugarCRM. I may try to get that up and running for an evaluation soon. I have found a job in Omaha at Securities America. I am very excited about this opportunity.

I am in Gretna Nebraska

I am officially in Gretna Nebraska… Looking hard for a position in ASP.net as a developer. I am going to look at a house to rent today at 6:00 pm. I am hoping to get completely moved soon so I get to working on training videos for this Blog. Please keep checking for them to be released soon.

Developing blog post on Android

Wow!! WordPress for android is very very cool. You can blog with your android phone.  It will even allow you to add images. Type in wordpress in the marketplace and you are on your way.

Android Utility

I wanted to share another application that I have discovered in my toolbox of cool applications. This application is a free application that will allow you to Tether your Android phone to your computer for Free!! This application works very well for me using the Droid X and my Laptop. You have to install a small app on your phone and on your Computer. Just type in PDANet in the Android Market Place.

Responses from Synergy

Hello everyone I have had a lot of responses on setting up the synergy. So here is my attempt to explain how to setup and use the application.

The first and obvious thing is to install it, I assume (ass-u-me) you know how to do that. If not leave me a comment below and I can help you. Anyway the first screen that will show up is this:



The main computer that you have the physical keyboard and mouse on you will want to select the Radio button that says: Share this computers Keyboard and Mouse (server).

On the other computers you will select the Radio button: Use another computers shared keyboard and mouse (client). In the – Other computer’s host name: you type the name of the computer that has the physical keyboard and mouse. Where you see my “R2Server”.

Now on the computer that is sharing the keyboard and mouse you will need to click the “Configure” button. Clicking on the button will bring up this screen.

With this screen you will click on the Top + button that will bring up a screen and you will enter all the names of the computers that are going to be connecting and sharing the computer.

Then you will select the drop-down boxes that will configure the screen percentage of controlling the screen settings. Then comes the only really tricky thing that I have found in the entire program: **After you have the boxes set up right you have to click the + sign to add this to the links box.** When you have it all complete push the OK Button.

Some other advantages for the application are that you have a Advanced Button which will allow you to set up a port for your program. You can have the program start when you log in or when your computer starts.

A couple of other tricks I have discovered is that when you have the mouse on a screen/computer that needs to send a  “CTRL / ALT / DEL”  you cant use                  “CTRL / ALT / DEL” however because it will only do that on the computer the keyboard is physically connected to. You can use the “CTRL / ALT / PAUSE-BREAK” key combo to send a “CTRL / ALT / DEL” to the other computers.

Must have utility for all computer geeks!

This utility is one of the best utilities I have ever used and I have found that a lot of people don’t know about it. Well let me tell the world of computer geeks this is a must have utility.

Synergy – the web site is: http://synergy-foss.org/

This application is one of the greatest apps I have ever used. A virtual keyboard, video, mouse (KVM) without the V for Video in KVM application with a very cool twist! This application is a KM with multiple computers, multiple monitors, single keyboard and single mouse utility. The program is able to be set up on Windows, Linux and Mac. I have used it for about 3 years now and have never had an issues once it is set up.

My opinion is that everyone that has multiple computer and laptops (Like I Do) this is a must have application!! Check it out again at this site: http://synergy-foss.org/

 

My futile attempt at a blog!

Hello world, this is my first attempt to blogging. If I am as successful at this as I am developer I will not have any followers. I hope to begin posting code on stuff that I am trying to learn and will do my best on teaching others along the way. I am hoping to discover ways to improve my programming and help others. A little about my self, On July 22, 2005 I was diagnosed with Large Diffuse B-Cell Lymphoma Cancer. I was re-diagnosed with Burkett’s Type-A Lymphoma on on April 11, 2006. I am very happy to say that on July 26, 2011 I will be a 5 year cancer survivor!! Anyway I am hoping to live long time and along the way continue to learn as much as possible.

%d bloggers like this: