December 31, 2012

SharePoint Fundamentals: Document ID Service

What:
The document ID feature creates identifiers that can be used to retrieve items independent of their current location. The document ID service that supports it generates and assigns document IDs.​ Read details in MSDN
How:
Just go to site collection features and enable Document ID Service feature.
Once this feature is enabled, you will see configuration link in Site Settings.

You will be able to set some configuration related to DocumentID that is auto-generated in the Document ID Settings

And finally, when you upload any document to any of the document library in site collection, you will see document Id is automatically assigned to the library.

Conclusion:
You must be thinking what is so good about this?
DocumentID service provides a web part to search any document by ID. You can place that web part in home page and anybody knowing(or not knowing) documentId that they are interested in can directly go do document whithout navigating site hierarchy. In case of multiple results list of documents will be displayed. This will work at site collection level for any document in site collection at any level deeper in site hierarchy.
References:
1.MSDN,
2.Tobias Zimmergren's blog This blog presents much more details than what I copy pasted above! It is more than enough to know whatever you know as an analyst, programmer, tester or administrator.

If you have any questions you can reach out our SharePoint Consulting team here.

December 27, 2012

Powershell - Remove User account permissions from all sites

Use Cases:
When you create a site with unique permissions and break role inheritance at list or list item level, sharepoint will automatically add SHAREPOINT\System or site collection admin directly to Site Permissions. Here is the script that you can use to remove those users.
How​
 function RemoveAccountFromAllSites ($siteURL, $accountName, [switch]$skipRootSite)
 {
    #Get Site Collection
    $site = Get-SPSite $siteURL
 
    #Check if the accountName variable contains a slash - if so, it is an AD account
    #If not, it is a SharePoint Group
    $rootWeb = $site.RootWeb
    if ($accountName.Contains("\")) { $account = $rootWeb.EnsureUser($accountName) }
    else { $account = $rootWeb.SiteGroups[$accountName] }
 
    $rootWeb.Dispose()
    
    #Step through each site in the site collection
    $site | Get-SPWeb -limit all | ForEach-Object {
        
        #Check if the user has chosen to skip the root site - if so, do not change permissions on it
 
        if (($skipRootSite) -and ($site.Url -eq $_.Url)) { write-host "
Root site" $_.Url "will be bypassed" }
        else {
            #Check if the current site is inheriting permissions from its parent
            #If not, remove permissions on current site
            if ($_.HasUniqueRoleAssignments) {
                #write-host "
Removing account" $accountName "from site" $_.Url
                $_.RoleAssignments.Remove($account)
            }
            else {
                write-host "
Site" $_.Url "will not be modified as it inherits permissions from a parent site."
            }
        }
    }
    #Display completion message and dispose of site object
    #write-host "
Operation Complete."
    $site.Dispose()
}
Conclusion:
Script will check if site has unique permissions or not. Skips and don't do anything if site is not having unique permissions. Does what is expected if site is having unique permissions.
If you have any questions you can reach out our SharePoint Consulting team here.

Powershell - Creating log files for installation package

Use case:
It is general practice that we deliver wsp and powershell script to install it.
Why:
it is good practice to log whatever we show in screen to file so that it will be easy for sharepoint admin to send the result of installation.
How:

 # Set Execution Policy 
Set-ExecutionPolicy unrestricted
 
$date     = Get-Date
#read parameters from command line
$CurrentDir= Split-Path -parent $MyInvocation.MyCommand.Definition 
 
$timeStamp = (Get-Date).ToString("yyyyMMddhhmmss") 
$logFile = $CurrentDir+ "\install_" + $timeStamp + ".log"
start-transcript -path $logFile -noclobber 
 
#add this at end of script
Stop-Transcript 
#this is to show stop-transcript 
Remove-PsSnapin Microsoft.SharePoint.PowerShell    
Conclusion:​
$CurrentDir will get installation folder. Start-Transcript is powershell command to copy whatever message printed to console to file provided in parameter.
You have to place your installation script between start and stop transcript commands and everytime you execute the script, it will generate a separate log file that will have all details.

If you have any questions you can reach out our SharePoint Consulting team here.

Powershell - Add newly added field to all views


#Add-PSSnapin Microsoft.SharePoint.PowerShell
cls
$web = Get-SPWeb -Identity "url of web"
#list of views which needs to be changed
$views = @("All Documents","View1","View2")

$list = $web.GetList("ListUrl")
foreach($vwName in $views)
{
    $vw = $list.Views[$vwName]
    #Add new field
    $vw.ViewFields.Add("fieldName")
        #position is 0 based
    $vw.ViewFields.MoveFieldTo("fieldName",2)
    
    $vw.Update()
    Write-Host $vwName, "Updated"
}
 
If you have any questions you can reach out our SharePoint Consulting team here.

October 22, 2012

Nuget for Visual Studio

Nuget​ is a package manager for visual studio. It allows developers to setup third party libraries in the project easily. For example if you are working on a console application to migrate documents and want to use log4net library. You can just search for log4net in package manager gallery and add reference to it. All web.config/app.config and references will be auomatically updated by nuget.
Install nuget to your visual studio and start learning new libraries now!


If you have any questions you can reach out our SharePoint Consulting team here.

log4net - logging makes easy

Use case:
You are working on some task which requires logging to event viewer, file, console or combination of such mediums.
Why?
Most of the time you have to write same string to console and file with two different lines of code. That will cause the code look ugly and while changing messages, developer has to make sure to update both lines. Additional errors may occure due to the mistakes.
Prerequisites:
Install nuget for visual studio.
How?
Right click on your project and click on library package manager. Search for log4net and choose appropriate version as per your visual studio application. Click on install.
What are different mediums where I can log? 
  • MS SQL Server
  • MS Access
  • Oracle 9i
  • Oracle 8i
  • IBM DB2
  • SQLite
  • Asp.Net Trace
  • Console
  • EventLog
  • File
  • SMTP
  • much more
Example:
See vss_br/bms/trunk/bms/bmsmigration project in vss for rerence implementation in console application for logging in console and file.
References:
  1. Code project tutorial
  2. Configuration Examples
  3. Log4net config example to Log into console and file both
  4. Official Home page


If you have any questions you can reach out our SharePoint Consulting team here.

How to use ASMX services in visual web part development

Use case:
Visual web part needs to fetch data from aspx web service. WSDL url is provided.
Service reference vs Code generation:
There are two ways to add reference to asmx services. You can directly right click the web part project and click on add service reference, click on advance and then choose asmx service reference.
Adding service reference will hard code the service url. So it is suggested that we use WSDL.exe available in .net framework tools to generate a client proxy.
How to use WSDL.exe to generate service proxy?
  1. Go to .net command prompt
  2. type wsdl /language:csharp /out:c\csfilename.cs
This will automatically generate the cs file provided in out paramter. Add the class to your web part folder and adjust the namespace.
Further Considerations:
  1. Url of the service should not be hard coded, it should be coming from web part property.
  2. To imlpement this, add a custom property in web part to store service url
  3. Add another paramterized constructor to the first class. See example below:
    Default constructor:
     public Spotlight()
            {
                this.Url = "web service url";
            }
    New constructor:
     public Spotlight(string _url)
    {
      this.Url = _url;
    }
  4. Generally the first class in wsdl generated proxy cs will be the one where you need to add the new constructor.
  5. You can confirm this by looking at the first class and it will be inheriting from
          "System.Web.Services.Protocols.SoapHttpClientProtocol" class.
  6. When web part property for service url is blank, use default constructor
  7. When web part property for service url is not blank use parameterized constructor.
  8. When your service will change, you have to repeat the process to generate proxy and add additional parameterized constructor
Other best practices:
  1. Always use proper error handling to make sure exceptions are not visible to end users
  2. Always show appropriate message in case of no data to users
  3. Always show appropriate message in case of error getting data from service
  4. Always use best practice to parse xml data.
  5. If possible use xml deserializers to convert xml data into List
Conclusion:
We find it very useful to use WSDL.exe to generate asmx proxy and using constructor injection to initialize the service url from web part property.

If you have any questions you can reach out our SharePoint Consulting team here.

SPLongOperation

Use Case:
SPLongOperation class Sets the Web page image to the image used by the server to indicate a lengthy operation (typically, an animated image with associated text).
So, when you are starting a workflow, or doing some server side processing that can take long period than asp.net request execution timeout period, you can use this class to do such operations.
Usage:
   1:  SPLongOperation.BeginOperation beginOperation = null;
   2:                  if (beginOperation == null)
   3:                  {
   4:                      beginOperation = delegate(SPLongOperation longOperation)
   5:                      {
   6:                          // Long running code here ...
   7:                          longOperation.End(this.workflowList.DefaultViewUrl, SPRedirectFlags.UseSource, HttpContext.Current, "");
   8:                      };
   9:                  }
  10:                  SPLongOperation.Begin(beginOperation);
 
 
Notes:
You need to import System.Threading. At the end of your operation, generally you do longOperation.End() and page will be redirected to the specified url. If you are doing it in sharepoint dialog, it will automatically close dialog and redirect parent page.

If you have any questions you can reach out our SharePoint Consulting team here.

Printing InfoPath Forms

Print option is normally not available as an option on Ribbon in InfoPath templates. So if one wants an option to “Print” InfoPath form then they can use the following steps below. Before starting off the InfoPath should be published as a Content type and a Page with InfoPath form Web Part must be created.
  • Open the Display Form web part page (make sure to select the correct content types if you have more than one....). You can do this by clicking Form Web Parts > (Content Type if you have several) Display Form
  • Edit the InfoPath Form Web Part. Set the Chrome to include just the Title.
  • Add a Content Editor Web part to the page. Set it to Hidden.
  • Add the JS from below link in the HTML source of the Content Editor Web part.
    https://www.nothingbutsharepoint.com/sites/eusp/Pages/jquery-for-everyone-print-any-web-part.aspx
  • Save the page.
You can now click the little icon (or you can modify the JS to insert a button to say 'Print Form') and the Print Preview of the Info Path web part gets opened, along with popup for setting printer options.
In the above JS script, the function “printWebPart” can be modified and replaced by the below script function

  printWebPart(tagid)
        {
            if (tagid)
                {
                    this.print();
                }
        }
 

This will directly open up the popup for setting printer options without showing the Print Preview.

If you have any questions you can reach out our SharePoint Consulting team here.

July 2, 2012

How to use soapUI to review ListData.svc

sIntroduction
SoapUI is a free tool that can be used to test out of the box ListData.svc service provided by sharepoint. This service is available at /_vti_bin/ListData.svc for any of your sharepoint site. Here is how we can try it out using SoapUI.
Step1: Install sopa UI and click on File > New SoapUI Project. Add some project name and check "Add REST Seervice:" like shown in following figure and then click OK

Step2: After clicking on OK another window will open like following, just click on OK

Step3: New REST resource window will appear. In resource name enter site url and in resource path/endpoint provide list/document library name and click on "Extract params" button. Following is the screen that shows sample data.

Step4:That will automatically create a new request called Request 1.This request will automaticlaly detect endpoint and path to your list/document library. If it is not, just click on"-no endpoint set-" and click on add new endpoint. Enter site url in the dialog again.

Step5: Maximize "Request 1" window in soapUI. In botton left corner you will see " ... ", click on it and you will be able to provide sharepoint authentication details there.

Step6: Once you are done with authentication details you can click on execute icon at top left corner of "request 1" window (marked in above figure) to execute the request and you will be able to see response at right hand side window.
Step7: ListData.svc can also return json data in response out of the box. Just try to provide accept = application/json like shown in figure below:


If you have any questions you can reach out our SharePoint Consulting team here.

SMTP Server For Development Farm – smtp4dev

Developing for SMTP can be a time consuming hell. One can work out encoding issues the hard way – with a proper SMTP server installed – or skip all that and make it easy. Enter SMTP4Dev's, which emulates an SMTP server, and allows one to see what's being sent around in much easier way.
Scenario:
I am working for the alert me functionality for the list and List Items modification and deletion but due to some configuration problem in my development environment,
I did not receive e-mail in consistent manner
After some goggling I have found one very useful project in codeplex for testing local smtp functionality without any installation.
Smtp4dev.exe does not require any installation.
  • Double click and open smtp4dev.exe
  • Click on option button and go to server tab
  • Set domain name anything you like for example: local.abc.com
  • Click Ok.
Now Open your Central Administration
  • Go to System Settings à Configure outgoing e-mail settings
  • Provide that same name of your domain name in Outbound SMTP server
  • Provide anything with domain name as from address. For example: test@ local.abc.com
  • Provide anything with domain name as Reply-To address. For example: Reply@ local.abc.com
Note: Make sure that the domain name provided in smtp4dev and the domain name in from address and to address are same.
Next,
  • Open C:\Windows\System32\Drivers\Etc
  • Open local file with administrator rights using any text reading software like notepad.
  • Enter entry like à 127.0.0.1 local.abc.com
    (Make sure, this name must be same as Domain name in smtp4dev.exe)
  • Save and close
Now whenever your share point server will send any mail, it is captured and displayed as shown in screenshots below.

This is a mail sent by share point which you can Inspect, in order to see the contents of the email sent, check the encoding, etc.:

If you want to get fancier, the proxy server allows for customizing the way it behaves:


If you have any questions you can reach out our SharePoint Consulting team here.

June 18, 2012

SharePoint Search: Partial Page Exclusion

Out of the box, SharePoint provides a mechanism for excluding publishing pages from the search index by any number of criteria, but what if you want to exclude only parts of a page? This becomes useful when you have content on numerous pages that contains common keywords.
For Example, In Our Production site we have master page and in this master page , Header , Left Navigation and footer for the Pages.
So when someone performs a search for "Careers" they will get back every page in your site, instead of just the Careers and related Careers pages. To prevent this, we needed a way to keep SharePoint from indexing that content when it's performing a crawl.
Web Control
We decided that a System.Web.UI.WebControls.Panel control would be a good model to build my control on. It allows you to easily drop it in the page layout using SharePoint Designer, and you can put other html and controls within it. I didn't want to inherit from the Panel control though, because it adds unwanted 'div' tags to the rendered output. The key to the Panel control's behavior are the following two attributes on the class:
[ParseChildren(false), PersistChildren(true)].
These attributes allow the content within the control to persist as controls and not properties of this control.
User Agent
The second part of the equation is knowing when to show or hide the contents of the web control.
SharePoint gives us a way to identify that it's performing a crawl through the UserAgent property of the http request by adding "MS Search" to it.
Code
Putting this all together we come up with the following class:

[ParseChildren(false), PersistChildren(true)]
    public class SearchCrawlExclusionControl : WebControl
    {
        private string userAgentToExclude;

        public string UserAgentToExclude
        {
            get
            {
                return (string.IsNullOrEmpty(userAgentToExclude)) ? "ms search" : userAgentToExclude;
            }
            set
            {
                userAgentToExclude = value;
            }
        }

        protected override void CreateChildControls()
        {
            string userAgent = this.Context.Request.UserAgent;

            this.Visible = (!string.IsNullOrEmpty(userAgent)) ? !userAgent.ToLower().Contains(UserAgentToExclude) : true;

            base.CreateChildControls();
        }

    } 
Using It
Register Web Control within Page.
<%@ Register Tagprefix="SearchUtil" Namespace="ABC.SharePoint.WebControls" Assembly="ABC.SharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxx" %>
After adding the register tag to the page layout, we can wrap all the content we want to exclude with our control:
<SearchUtil:SearchCrawlExclusionControl ID="SearchCrawlExclusionControl1" runat="server">
    <div>Some Content To Excludediv>
SearchUtil:SearchCrawlExclusionControl>
Test this:
After applying this User control to all your excluding Div and HTML tags.
Make Incremental or Full crawl of you web site.
How to edit the User Agent string in Mozilla FireFox
To change the User Agent string, just enter about:config as an address in the address bar of FireFox, the location where you normally enter a URL (link). I recommend to preserve the original value, which you can get when you enter just about: in the address bar.
Now press the right mouse button to get the context menu and select "String" from the menu entry "New". Enter the preference name "general.useragent.override", without the quotes. Next, enter the new User Agent value you want Mozilla Firefox to use.
I added my name and a link to my web site to the original value. You can also pick one from the list of User Agent strings. Check the new value by entering about: in the address bar.
How to edit the User Agent string in Google Chrome
Here's how to change the user agent:
  • open the Developer Tools (Ctrl+Shift+I on Windows/Linux, Command - Option - I on Mac OS X)
  • 2. click the "settings" icon at the bottom of the window
  • 3. check "override user agent" and select one of the options (Internet Explorer 7/8/9, Firefox 4/7 for Windows/Mac, iPhone, iPad and Nexus S running Android 2.3).

You can also select "other" and enter a custom user agent.
Note: Here to test for SharePoint search write MS Search as User Agent in Other option.
How to edit the User Agent string in Internet Explorer
To change it open your registry and find the key
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\User Agent\Post Platform].
Each value name listed in this key will be sent to the remote web server as an additional entry in the user agent string. To remove any additional information delete the values within the [Post Platform] key. To add additional entries create a string value and name it the string you want to be sent.
Restart Internet Explorer for the changes to take effect.
Note:Here to test for SharePoint search write MS Search as User Agent in Other option.
If you have any questions you can reach out our SharePoint Consulting team here.

June 11, 2012

Creating a Custom Action by Using a Feature

The following steps create a custom action in Visual Studio 2010.
The procedures in this section assume a development environment where SharePoint 2010 is installed and configured, Microsoft Visual Studio 2010 is installed and the currently logged-in user has administrative rights on the SharePoint environment for deployment purposes.
To Create a Custom Action by Using a Feature
  • In Visual Studio 2010, click New Project, expand the SharePoint node, click 2010, and then click Empty SharePoint Project. Name the project E-mail a Link and then click OK.
  • In the SharePoint Customization Wizard, select the local SharePoint site that can be used for debugging and whether the solution will be deployed as a sandboxed or farm solution as shown in Figure 1.
  • Click Finish.
    Figure 1. Specify the deployment method 

  • In Solution Explorer, right-click the Features node and then click Add Feature as shown in
    Figure 2.
    Figure 2. Add new feature
  • Name the feature E-mail a Link and add a description as shown in Figure 3.
    Figure 3. Name the feature
  • In Solution Explorer, right-click the E-Mail a Link project, select Add, and then select New Item as shown in Figure 4.
    Figure 4. Add a new item to the project
  • In the Add New Item dialog box, select the Empty Element template, type E-Mail a Link as the name, and then click Add as shown in
    Figure 5.
    Figure 5. Add an element to the project
  • Open the Elements.xml file inside E-Mail a Link and then replace the file content with the following code example. If you like to apply this E-mail a Link to all the Lists, Change RegistrationsType From "ContentType" to "List" and RegistrationId from unique number to "101"
    XML
    1. <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <CustomAction
      Description="Email A Link"
      Title="Email A Link"
      Id="{E538E8C7-65DA-454E-AD87-4A603B6CC569}"
      Location="CommandUI.Ribbon"
      RegistrationId="0x0100...(put actual Id here)"
      RegistrationType="ContentType"
      Sequence="1"
      Rights="ViewListItems"
    xmlns="http://schemas.microsoft.com/sharepoint/">
    <CommandUIExtension xmlns="http://schemas.microsoft.com/sharepoint/">
    <!-- Define the (UI) button to be used for this custom action -->
    <CommandUIDefinitions>

    <CommandUIDefinition Location="Ribbon.ListForm.Display.Actions.Controls._children">
    <Button Id="{B511A716-54FF-4EAE-9CBE-EA02B51B626E}"
    Command="{4E2F5DC0-FE2C-4466-BB2D-3ED0D1917763}"
    Image16by16="/_layouts/1033/images/formatmap16x16.png"
    Image16by16Top="-16" Image16by16Left="-88"
    Sequence="500"
    LabelText="E-mail a Link"
    Description="E-mail a Link"
    TemplateAlias="o2"
    />
    </CommandUIDefinition>
    </CommandUIDefinitions>
    <CommandUIHandlers>
    <!-- Define the action expected on the button click -->
    <CommandUIHandler Command="{4E2F5DC0-FE2C-4466-BB2D-3ED0D1917763}" CommandAction="javascript:mailThisPage();" />
    </CommandUIHandlers>
    </CommandUIExtension>
    </CustomAction>
    <CustomAction Location="ScriptLink" ScriptSrc="/_layouts/xxxx/xxxx.js"/>
    </Elements>
  • Save the file.
  • Add the E-Mail a Link element to the E-mail a Link feature as shown in Figure 6.
    Add the E-Mail a Link element to the E-mail a Link
    feature as shown in Figure 6.
  • Right click the solution name and then click Deploy as shown in Figure 7. Visual Studio 2010 will build and deploy the solution to the farm.
    Figure 7. Build and deploy the solution
  • Navigate to the local site, Enable the feature E-mail a Link.
  • Add custom and name it as Promotion list, and then Click on View Item. Observe the "E-mail a Link" under the Action Group as shown in Figure 8.
    Figure 8. The E-mail a Link button
  • Click the "E-mail a Link" button and notice the default Email application open with the link to this item.
If you have any questions you can reach out our SharePoint Consulting team here.

May 30, 2012

CAML Designer: Have you tried it?


When you want to design/test your caml query, most of the time we use U2U CAML Query builder. Sometimes you get problem with connection but most of the time, it was working fine for most of the needs.
Recently, I tried CAML Designer which is really nice tool to try as alternative. WPF UI experience with many additional features may impress you to switch to this new tool.
Let us know your experience while evaluating CAML Designer.
If you have any questions you can reach out our SharePoint Consulting team here.

May 28, 2012

Generate test data using GenerateData.com

Introduction:
There are times when you need test data in order to test how your application scales. GenerateData.com helps you generate test data in many popular formats like html, xml, csv. excel etc. Let's see how we can use it.
How to:

  • Goto generatedata.com
  • Enter column name in column title and select Datatype from drop down.
  • For ID AutoIncrement Datatype is selected and in options (Start at ) 1 is entered because from which value user wants to start his id number.
  • And in increment it is given 1 because user wants to increase its id by 1.
  • Second field is inserted (Functional Group) whose DataType is custom list . The item of custom list is inserted in Enter values Seperated textbox and items should be separated by “|”.
  • If user has more rows then shown than user can add more values by entering exact figure and click on Row(s) textbox.​
  • After entering all data user has to select Result Type, For Result type option is given on top (HTML,Excel,XML,CSV,SQL), Select the desired Result Type. 
  • And finally click on generate button and if user has selected Excel for result type and an excel will generate and then user can import excel to Database.
Conclusion:
It is really easy and straight forward to genreate test data for almost any kind.
If you have any questions you can reach out our SharePoint Consulting team here.

May 23, 2012

PowerGUI script editor: powershell debugging and intellisense

​​​In this post I am going to show you how to use PowerGUI script editor for executing sharepont2010 powershell. There are two main advantages of using PowerGUI:
  • Dubugging of powershell script
  • Intellisense support
So, let's start setting up PowerGUI to use with sharepoint 2010:
  • Download and install latest version of PowerGUI.
  • Download PowerGUI PowerPack for sharepoint.
  • Start PowerGUI script editor​ and go to File > Powershell Libraries
  • Click on "Add Module" and add downloaded "PowerPack for sharepoint" library here
  • That will add another entry "Microsoft.Sharepoint.PowerShell" into the listing. Check the library to make it enable
  • Restart PowerGUI script editor and you are ready to get started.
If you have any questions you can reach out our SharePoint Consulting team here.

May 15, 2012

Managed metadata column limitation


There is an interesting article on managed metadata column limitation from sharepointanalysthq wihch describes many interesting limitations. That list is really useful. There are some useful suggessions that I want to add to the list:
  • Never export list/document library with managed metadata as template with data in order to copy it locally or othre places. Main reason behind the same is, managed metadata columns has term store, term set etc defined and they will not match in the destination managed metadata application and can cause problems
  • Never stop/remove taxonomy updater services, specially because they are responsible to make sure your manage matadata columns are having consistent and up-to-date data all the time.
  • One of the option for moving list/libraries with managed metadata column along with preserving all it's IDs is to use http://spdeploymentwizard.codeplex.com/ utility.
That's it for today, keep in touch for more managed metadata related interesting findings.

If you have any questions you can reach out our SharePoint Consulting team here.

May 10, 2012

Performance analysis: Part 2

In previous post we used Stopwatch object in order to compare time taken by SPList.​ItemCount and SPList.Items.Count. Here are additional things to add in list.
  • If you are using SPList.Items.Add, start using SPList.AddItem. Since reference to SPList.Items properly will load list data it will not perform good.
  • If you are accessing list, try to use caml query to access it and always use RowLimit and view field properties to limit output to exactly what you want.
  • use ContentIterators in place of foreach when you want to iterate list items.
If you have any questions you can reach out our SharePoint Consulting team here.

April 30, 2012

Using HttpContext.GetGlobalResourceObject in webpart development

We found interesting issue during working with global resource files this week.

Problem:
Event if we are using HttpContext.GetGlobalResourceObject, web part was rendering data in English even if site language is other than English!

If we switch to edit mode, it was working sometime, but most of the time it was showing English text.

Root cause:
We tried creating a new application page and placed a webpart there, it was strange that it was working properly in the application page.

We finally found that at the time of reading resources through  HttpContext.GetGlobalResourceObject web part was not aware of the current UICulture

Solution:
Before:

   1:  var strLinkText = HttpContext.GetGlobalResourceObject("file", "key");
After:​

   1:  var strLinkText = HttpContext.GetGlobalResourceObject("file", "key",SPContext.Current.Web.UICulture);

Conclusion
Finally after passing third argument from SPContext.Current.Web.UICulture it worked properly
If you have any questions you can reach out our SharePoint Consulting team here.

April 23, 2012

Creating your first data cube.

SQL Server 2005/2008 comes along with the Business Intelligence Development Studio (also known as BIDS) which is used for creating projects related to analysis services, integration services, report server and report models (used to design reports on client side). In order to get started with BIDS to build your first analysis services project, you need to have the following SQL Server components installed: SQL Server Database Engine SQL Server Analysis Services (SSAS) Business Intelligence Development Studio A good working data warehouse Below are the steps to be followed to create the cube 

Create a new Analysis Services project

For creating a new project in BIDS, you’ll find the Business Intelligence Development Studio (BIDS) in Start > Microsoft SQL Server 2005/2008 folder. Once you’re in the business intelligence development studio, click File > New > Project from where you could create a new Analysis Services Project. Give it any name you like and click on ok. 

Define a data source

To define a data source, you'll use the Data Source Wizard. You can launch this wizard by right-clicking on the Data Sources folder in your new Analysis Services project. The wizard will walk you through the process of defining a data source for your cube, including choosing a connection and specifying security credentials to be used to connect to the data source. 

Defining a Data Source View

A data source view is a persistent set of tables from a data source that supply the data for a particular cube. BIDS also includes a wizard for creating data source views, which you can invoke by right-clicking on the Data Source Views folder in Solution Explorer. You can select from existing tables and set relations between them or enter in your own statements using “Edit Named Query”.
Now you can move further either creating Cube using Cube Wizard which automatically creates Dimensions to be used in the cube or by creating a Dimensions and using it in the Cube.

Creating Dimensions

BIDS also provides wizard for creating dimensions. It helps in defining the key columns and attributes to be in used within a cube. 

Creating Cubes

Cube wizard appears within BIDS for creating cubes where in measurement group tables are to be defined. Here option to either select from existing dimensions or create new dimensions is provided.

Deploying and Processing a Cube

To deploy the cube you just created, select Build > Deploy. This will deploy the cube to your local Analysis Server, and also process the cube, building the aggregates for you. BIDS will open the Deployment Progress window which will keep you informed during deployment and processing.

If you have any questions you can reach out our SharePoint Consulting team here.

Best Practice: Maintaining scripts in your SharePoint project


Introduction

Branding is the most important part of any SharePoint project. If you are planning to deliver branding in your release, you have to make sure your developer team is proactive to deliver quality branding from early stage of the project. In most of the branding project, jQuery and JavaScript becomes must-have part. Here, we will discuss practices that can be followed to ensure quality deliverables.

Practice
  • Manage script files
    From the very starting stage of your project, split your all JavaScript code in three files.
    • jQuery.min.js - This will contain jQuery reference and should be reference first in order.
    • jQuery.plugins.js - This should contain all custom plugins we used in it.
    • ProjectName.js - This should contain all your custom code written to get your project pages work properly.
  • Choosing plugins for your project
    • Download plugin bundle to your local computer.
    • Generally plugin will contain sample html files, jQuery and plugin script files.
    • First thing to check is jQuery version you are using in your project and the one which is used in the plugin.
    • If they are different, replace their jQuery.min.js with the one we are using.
    • Properly test the sample provided in plugin in all browsers you are planning to support.
    • Once browser and version compatibility matches paste plugin's min.js at end of jQuery.plugins.js file.
    • Implement plugin specific mark up wherever applicable.
    • Always use projectName.js to initialize plugin.
    • Repeat above process when you choose to add any jQuery plugin
  • Resolving CONFLICTS!
    Another challenging part is, jQuery ready not working or custom plugin you are using is disturbing your site's CSS. Here are thoughts on the same:
    • Always use _spBodyOnLoadFunctionNames.Push("yourFunctionName") to initialize your scripts in page load.
    • Always use only necessary CSS from what plugin CSS has provided and prefix class or ID in CSS as application. For example if a generic class .clear is used and you are calling plugin using $('#news') you should replace that with #news .clear. Do this for all CSS you include for the class.
Final thoughts
Here we've pointed out some of the best practices. Like this post? You would like to add/correct something? please provide your feedback on the same. 

If you have any questions you can reach out our SharePoint Consulting team here.

April 17, 2012

Performance analysis: Use SPList.ItemCount instead of SPList.Items.Count

Here is the code that can measure performance between two:

   1:  Stopwatch sw = new Stopwatch();
   2:   
   3:              using (SPSite site = new SPSite("http://site/"))
   4:              {
   5:                  using (SPWeb web = site.OpenWeb())
   6:                  {
   7:                      SPList list = web.GetList("/Lists/list");
   8:                      long totalMemory = 0;
   9:                      long totalCollectionCount = 0;
  10:                      Console.WriteLine("Good test");
  11:                      totalMemory = GC.GetTotalMemory(false);
  12:                      totalCollectionCount = GC.CollectionCount(0);
  13:                      sw.Start();
  14:                      Console.WriteLine("item count:{0} ", list.ItemCount);
  15:                      sw.Stop();
  16:                      Console.WriteLine("Total time taken:{0}", sw.Elapsed);
  17:                      Console.WriteLine("TotalMemory:{0}", GC.GetTotalMemory(false) - totalMemory);
  18:                      Console.WriteLine("CollectionCount:{0}", GC.CollectionCount(0) - totalCollectionCount);
  19:   
  20:                      GC.Collect();
  21:   
  22:                      Console.WriteLine("\nBadTest");
  23:                      totalMemory = GC.GetTotalMemory(false);
  24:                      totalCollectionCount = GC.CollectionCount(0);
  25:                      sw.Start();
  26:                      Console.WriteLine("item count:{0} ", list.Items.Count);
  27:                      sw.Stop();
  28:                      Console.WriteLine("Total time taken:{0}", sw.Elapsed);
  29:                      Console.WriteLine("TotalMemory:{0}", GC.GetTotalMemory(false) - totalMemory);
  30:                      Console.WriteLine("CollectionCount:{0}", GC.CollectionCount(0) - totalCollectionCount);
  31:   
  32:                      Console.WriteLine("Press Any key to exit...");
  33:                      Console.ReadKey();
  34:                  }
  35:              }
Results of your testing will depend upon items in list for Items.Count but it will be constant for Items.ItemCount

If you have any questions you can reach out our SharePoint Consulting team here.

April 9, 2012

Command line parser like stsadmin in sharepoint console app


In our recent console application we decided to provide sharepoint Consultant administrators similar experience like stsadmin while providing custom features for administration and analysis. So we used an open source command line parser (codeplex) in order to implement command line parsing.

It has been proven a good choice. Here is how we can easily use it.

Source code:

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Text;
   4:  using CommandLine;
   5:  using CommandLine.Text;
   6:  using Microsoft.SharePoint;
   7:  using Microsoft.SharePoint.WebPartPages;
   8:   
   9:   
  10:  namespace SPAdmin
  11:  {
  12:      class Program
  13:      {
  14:          static Options options = new Options();
  15:          static StringBuilder fileOutput;
  16:          static void Main(string[] args)
  17:          {
  18:              ICommandLineParser parser = new CommandLineParser(new CommandLineParserSettings(Console.Error));
  19:              if (!parser.ParseArguments(args, options))
  20:                  Environment.Exit(1);
  21:   
  22:              if (string.IsNullOrEmpty(options.operation))
  23:              {
  24:                  Console.WriteLine(options.GetUsage());
  25:                  Console.WriteLine("Press any key to exit...");
  26:                  Console.ReadKey();
  27:                  Environment.Exit(1);
  28:              }
  29:   
  30:              switch (options.operation.ToLower())
  31:              {
  32:                  case "Operation1":
  33:                      DoOperation1();
  34:                      break;
  35:                  case "Operation2":
  36:                      DoOperation2();
  37:                      break;
  38:              }
  39:   
  40:              Console.WriteLine("Press any key to exit");
  41:              Console.ReadKey();
  42:          }
  43:          private static void DoOperation1()
  44:          {
  45:             
  46:          }
  47:          private static void DoOperation1()
  48:          {
  49:             
  50:          }
  51:          private sealed class Options
  52:          {
  53:              [CommandLine.Option("o", "operation",
  54:                  Required = true,
  55:                  HelpText = "Name of operation\n ")]
  56:              public string operation;
  57:            
  58:   
  59:              [HelpOption(HelpText = "Dispaly this help screen.")]
  60:              public string GetUsage()
  61:              {
  62:                  var help = new HelpText("Test");
  63:                  help.AddOptions(this);
  64:                  return help;
  65:              }
  66:          }
  67:   
  68:      }
  69:   
  70:   
  71:  }

Details:
1. Create a new console app. (If you have CSK templates installed, you can create new sharepoint console app project.)
2. For defining options, add options class as an inner class to your Program.cs
3. In main method, parse the passed parameters.
4. try it with SPAdmin -o "operation1" and see what happens
Add options as you need! Nice and clean way to implement various operations.

If you have any questions you can reach out our SharePoint Consulting team here.