Get the port number of your Web Application Zone using server side object model

Although it seems pretty easy to get your web application’s port number from IIS or Central Admin, I didn’t find enough info on how to get the port number from server side object model. I was trying to customize the Authenticate.aspx application page where I had already written code to check users permission in a specific group of another web application. In the end, I was able to get a really simple method which is the following piece of code:

int webPort=SPContext.Current.Site.WebApplication.IisSettings[Microsoft.SharePoint.Administration.SPUrlZone.Default].ServerBindings[0].Port; if (webPort==80) { //check user permission for a site collection which is using the web app on port 80 ... ... }

else { //check the user permission for rest of the web apps SPUtility.EnsureAuthentication(); SPUtility.Redirect(spWeb.Url, SPRedirectFlags.UseSource, Context); }

If you look at the code, you’ll easily understand I was actually trying to check the user permission for the web application which is using Port 80 and you can write your server side code there to check any user’s permission or group permission etc. Notice that, here I am actually checking the default zone’s port number for the web application. If you have multiple zones, or else if you have extended your web application on other zones which have different ports, then you have to specify  one from the below under WebPpplications.IisSettings property:

SPUrlZone.Custom,
SPUrlZOne.Default,
SPURlZone.Internet,
SPUrlZone.Intranet
SPUrlZOne.Extranet

Now, what if you want to create a method, which will get the port number of web application and later on you can call that method from anywhere; you can do that too. The code is given below:

int GetPortNumber(Microsoft.SharePoint.Administration.SPWebApplication application)
{
int result = 0;
Microsoft.SharePoint.Administration.SPIisSettings setting=null;
if (application.IisSettings.TryGetValue(Microsoft.SharePoint.Administration.SPUrlZone.Default, out setting))
{
if (null != setting)
{
var serverBindings = setting.ServerBindings;
if (0 < serverBindings.Count)
{
Microsoft.SharePoint.Administration.SPServerBinding serverBinding = serverBindings[0];
result = serverBinding.Port;
}
}
}
return result;
}
Advertisements

Create Dynamic Visual Web Part in SharePoint

After a long time, I am going to discuss about creating a  dynamic visual web part in SharePoint 2010. Suppose, a company needs to create a sales forecasting web part on monthly basis. They want to display information in a web part of a page where the data will come from different lists from a web site and hence the result will be shown visually to highlight information based on conditions.

Objective:

Select a month from the drop down list of all months and based on the selected month, the grid view should change automatically. A LINQ will be executed in the background whenever you change a month from the drop down list and the data displayed inside the grid view should match the query results.

Solution:

First of all, Create a  visual studio project and select Visual Web Part from the SharePoint 2010 templates. This automatically adds a Feature with a Default Visual Web Part in your solution. Please note that, while creating a visual web part, you must choose as Farm Solution as the files of visual web parts (ASCX Files) need to be deployed physically inside 14 hive.

You will need to write LINQ to query your SharePoint Lists. So, create a Entity Class using SPMetal.exe. To know more about how to use SPMetal, go here. Create and add the entity class in your project. For my example; I named the class as MyEntity.cs.

To start off with the solution, let us drag and drop a drop down box and create SPGridView object. The ASCX code is given below:

  1. <%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
  2. <%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
  3. <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
  4. <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
  5. <%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
  6. <%@ Import Namespace="Microsoft.SharePoint" %>
  7. <%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
  8. <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="VisualWebPart1UserControl.ascx.cs" Inherits="SalesForecastWebPart.VisualWebPart1.VisualWebPart1UserControl" %>
  9.  
  10. <asp:dropdownlist runat="server" ID="MonthList" AutoPostBack="True" onselectedindexchanged="MonthList_SelectedIndexChanged"
  11.     >
  12.     <asp:ListItem Selected="True">–Select Month–</asp:ListItem>
  13.     <asp:ListItem Value="1">January</asp:ListItem>
  14.     <asp:ListItem Value="2">February</asp:ListItem>
  15.     <asp:ListItem Value="3">March</asp:ListItem>
  16.     <asp:ListItem Value="4">April</asp:ListItem>
  17.     <asp:ListItem Value="5">May</asp:ListItem>
  18.     <asp:ListItem Value="6">June</asp:ListItem>
  19.     <asp:ListItem Value="7">July</asp:ListItem>
  20.     <asp:ListItem Value="8">August</asp:ListItem>
  21.     <asp:ListItem Value="9">September</asp:ListItem>
  22.     <asp:ListItem Value="10">October</asp:ListItem>
  23.     <asp:ListItem Value="11">November</asp:ListItem>
  24.     <asp:ListItem Value="12">December</asp:ListItem>
  25. </asp:dropdownlist>
  26.  
  27. &nbsp;&nbsp;<b>Monthly Forecast</b>
  28. <SharePoint:SPGridView ID="spGridView" runat="server"
  29.     AutoGenerateColumns="false"
  30.     onprerender="spGridView_PreRender" ondatabound="spGridView_DataBound" onrowdatabound="spGridView_RowDataBound">
  31.     <HeaderStyle HorizontalAlign="Left" ForeColor="Navy" Font-Bold="true" />
  32.     <Columns>
  33.         <SharePoint:SPBoundField DataField="Title" HeaderText="Consultant">
  34.         </SharePoint:SPBoundField>
  35.           <asp:TemplateField HeaderText="Total ITS Ricoh Lab Revenue">
  36.             <ItemTemplate>
  37.         <asp:Label ID="lblSales" runat="server" Text='<%# String.Format("{0:f2}",DataBinder.Eval(Container.DataItem,"TotalSales")) %>' ></asp:Label>
  38.         </ItemTemplate>
  39.         </asp:TemplateField>
  40.          <asp:TemplateField HeaderText="Total ITS Ricoh Lab Revenue Quota">
  41.             <ItemTemplate>
  42.         <asp:Label ID="lblQuota" runat="server" Text='<%# String.Format("{0:f2}",DataBinder.Eval(Container.DataItem,"ITSRicLabRev")) %>' ></asp:Label>
  43.         </ItemTemplate>
  44.         </asp:TemplateField>
  45.         <asp:TemplateField HeaderText="Status">
  46.             <ItemTemplate>
  47.                 <asp:Label ID="Status" runat="server" Text='<%# Eval("Status") %>' />
  48.             </ItemTemplate>
  49.              
  50.         </asp:TemplateField>
  51.       
  52.         
  53.     </Columns>
  54. </SharePoint:SPGridView>

If you look inside the above code, you will find that I have created four columns inside the grid view to display Employee (Consultant) Name, Total Revenue, Total Revenue Quota and Status and a drop down box containing all months. Now, create the entity object for the lists inside your ascx.cs file. For my scenario, I had to query two different lists and I created the entity and data context object as below:

EntityList<SCTXPSITSVCsForecastingItem> SCTXPSITSVCsForecasting;

EntityList<SolnConsultantsItem> SolnConsultants;

protected void Page_Load(object sender, EventArgs e)

{

    string spWebUrl = SPContext.Current.Web.Url;

    MyEntitiesDataContext dc = new MyEntitiesDataContext(spWebUrl);

    SCTXPSITSVCsForecasting = dc.GetList<SCTXPSITSVCsForecastingItem>(@"SCTX PS / ITSVCs Forecasting");

    SolnConsultants = dc.GetList<SolnConsultantsItem>("SolnConsultants");

 

}

 

From the above code, you can see I created two data context object where my entity class was “MyEntities”. I then called the two lists in the page load event by the GetList() Method.

Inside the SelectedIndexChanged() method of the drop down list for month, I called a method to create the LINQ and passed the selected item as the parameter. If you notice the LINQ below, you will see that I have used a join query to select data from two different lists. For my scenario, I had a list called “SCTXPSITSVCsForecasting” where there was a column named “ITSRicohLaborRevenue” in which all the employees (consultants) monthly forecast had to be summed up. So, I used an aggregated function (SUM) to sum up all the employees monthly forecast and divided by the standard monthly forecast to determine their status (if greater than 90%, “Green”, if greater than or equal to 75%, “Yellow” and if below 75%, “Red”).

  1. protected void MonthList_SelectedIndexChanged(object sender, EventArgs e)
  2.         {
  3.             var selected = MonthList.SelectedValue;
  4.             getConsultants(Convert.ToInt32(selected));
  5.            
  6.         }
  7.         private void getConsultants(int mo)
  8.         {
  9.  
  10.             var ConsultantQuery = from c in SolnConsultants.ToList()
  11.                                   join s in SCTXPSITSVCsForecasting.ToList()
  12.  
  13.                                on c.Title equals s.Consultant
  14.                                   where s.CloseDate.Value.Month.Equals(mo)
  15.                                   group s by new { s.Consultant, c.ITSRicLabRev } into result
  16.                                   select new
  17.                                   {
  18.                                       Title = result.Key.Consultant,
  19.                                       TotalSales = result.Sum(s => s.ITSRicohLaborRevenue),
  20.                                       ITSRicLabRev = result.Key.ITSRicLabRev / 12,
  21.                                       Status = (((result.Sum(s => s.ITSRicohLaborRevenue)) / (result.Key.ITSRicLabRev / 12) * 100) > 90 ? "Green" :
  22.                                       (((result.Sum(s => s.ITSRicohLaborRevenue)) / (result.Key.ITSRicLabRev / 12) * 100) >= 75 ? "Yellow" : "Red"))
  23.  
  24.                                   };
  25.  
  26.             spGridView.DataSource = ConsultantQuery;
  27.             spGridView.DataBind();
  28.  
  29.  
  30.         }

To display the status of the forecast visually, I had to add another method for the grid view on RowDataBound():

  1.  
  2.         protected void spGridView_RowDataBound(object sender, GridViewRowEventArgs e)
  3.         {
  4.             if (e.Row.RowType == DataControlRowType.DataRow)
  5.             {
  6.                 Label lblStatus = e.Row.FindControl("Status") as Label;
  7.                 string status = Convert.ToString(DataBinder.Eval(e.Row.DataItem, "Status"));
  8.                 if (status == "Red")
  9.                 {
  10.                     DataControlFieldCell d = lblStatus.Parent as DataControlFieldCell;
  11.                     // change the backcolor like this
  12.                     d.BackColor = System.Drawing.Color.Red;
  13.                     // change the row color like this
  14.                     e.Row.BackColor = System.Drawing.Color.LightBlue;
  15.                     // change the text color like this
  16.                     lblStatus.ForeColor = System.Drawing.Color.White;
  17.                 }
  18.                 else if (status == "Yellow")
  19.                 {
  20.                     DataControlFieldCell d1 = lblStatus.Parent as DataControlFieldCell;
  21.                     d1.BackColor = System.Drawing.Color.Yellow;
  22.                     e.Row.BackColor = System.Drawing.Color.Aqua;
  23.                     lblStatus.ForeColor = System.Drawing.Color.Blue;
  24.                 }
  25.                 else
  26.                 {
  27.                     DataControlFieldCell d2 = lblStatus.Parent as DataControlFieldCell;
  28.                     d2.BackColor = System.Drawing.Color.Green;
  29.                     e.Row.BackColor = System.Drawing.Color.LightCyan;
  30.                     lblStatus.ForeColor = System.Drawing.Color.WhiteSmoke;
  31.                 }
  32.             }
  33.         }

You can see from the above code that I am changing the Background color , Foreground color of the row based on the Status column’s value.

After deploying and adding the web part on a page, you will get a following screen:

ricohsaleswebpart

ricohsaleswebpart1

You can see from the above screenshots that the gird view is changing dynamically based on the selected month. Following this basic example, you can create more complex dynamic visual web parts in SharePoint.

How to save a site as template (WSP) and then import necessary files from that WSP in VS 2010 and deploy to another site or site collection?

In SharePoint 2010, there is a nice feature provided by VS 2010 which lets the developer import the WSP into VS 2010 environment where you can select your necessary lists, libraries, reusable workflows and see all these in code view in Visual Studio environment. You can later on deploy this to any site or site collection on your server. Important thing to note that, VS 2010 only allows you to deploy locally which means you cannot deploy anything if your SP server exists elsewhere.

First, let us see how easily you can save a site as a template from the web interface:

Go to site settings of your site. From “Site Actions”, select “Save Site as Template” (Publishing feature needs to be enabled for a site to view this option for a site [not site collection])

 

image

Now, Fill up the name of the file which will be saved as. You can select “Include Content” if you want your custom forms and custom reusable workflows to be available in the solution package. If you keep it unselected, it will not save any custom forms or reusable workflows.

image

Now, after clicking “OK”, you will be redirected to the page where the solution package is saved as template. Click on the file to download and save it.

After saving the WSP file, open your Visual Studio 2010 in “Administrator” mode and follow the steps below:

image

Choose “Import SharePoint Solution Package” from Installed templates.

image

Specify your site or site collection URL.

image

Browse to the location where you saved the “WSP” file.

image

After clicking on “Next”, you will see all the files available inside that WSP.

image

Now, you can deselect all and select only the required ones; after click on “Finish” you may get this window which will show a warning about the dependencies. Click “Yes” if required.

 

image

 

After that you will get a message saying “The solution is imported successfully”.

image

Now, you will be able drill down into all the fields you chose before and see the code for each field in VS. After modifying (if you require so), you will need to click on “Deploy” to deploy the site to your preferred location (which you mentioned while creating the project, you can change the URL from Solution Explorer too).

Once deployed, you will be able to see the elements in your site’s “All Site Content” and the settings for the lists and libraries will be exactly as it was in the other site settings from where you saved the template.