Wednesday, March 30, 2011

SharePoint Error Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack

One of the scenarios of getting this exception is with improper usage of SPSecurity.RunWithElevatedPrivileges.

One of my posts here describes on proper usage of SPSecurity.RunWithElevatedPrivileges to address the same issue.

SharePoint SPSecurity.RunWithElevatedPrivileges Usage

SPSecurity.RunWithElevatedPrivileges is used to run or execute the set of code statements in the context of an Application Pool Account instead of Current Logged in User.

The below code snippet shows the implementation details.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(SPContext.Current.Site.ID))
{
using (SPWeb web = site.OpenWeb(SPContext.Current.Web.ID))
{
web.AllowUnSafeUpdates = true;
//Code to edit/delete the file in a library
web.AllowUnsafeUpdates = false;
}
}
});
SPContext.Current.Web can not be used directly with in the RunWithElevatedPrivileges block as the SPWeb object becomes a instance of current logged-in user's context and it gives the below error if tries to update any content in the same Web with READ only access.

Error : Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.

To address the issue, a new instance of SPSite and SPWeb should be cerated within the RunWithElevatedPrivileges code block as above.

SharePoint Layout Page for Only Administrator Accessible

SharePoint Layout (Application) pages are accessible by any user who has a least possible access/permissions for any of the sites in the server/farm.

A layout page access can be restricted to only Site Administrator by overriding the RequireSiteAdministrator property of LayoutsPageBase class.

The below code snippet shows sample implementation.
using Microsoft.SharePoint.WebControls;
public class MyLayoutPage : LayoutsPageBase
{
//It mmakes sure only site administrators can access this page
protected override bool RequireSiteAdministrator
{
get
{
return true;
}
}
protected void Page_Load(object sender, EventArgs e)
{
//Code goes here...
}
}
It is just one of the members, look at the post here to know about many other members/methods of LayoutsPageBase class.

SharePoint Manager Tool for Heirarchical View of Content

SharePoint Manager is a very userful and powerful tool for SharePoint developers for reverse engineering, just like .NET Reflector for .Net developers.

SharePoint Manager tool is from the same person who wrote WSPBuilder (another must have tool) in SharePoint Development.

This tool helps the developers to traverse all the content from FARM -> Web Application -> Site Collection -> Web Site -> Libraries -> List Item -> Field etc., in a heirarchical view in a explorer tree view.

It also gives the xml, data of a specific item, properties, caml query of views etc.,

Download the SharePoint Manager 2007/2010.

Tuesday, March 29, 2011

C# Code Quality Tools

Code quality is very important in delivering the reliable solutions.
But most of the developers simply write the code to implement a solution for the requirement.

I strongly recommend to analyse the code before delivering. I suggest the below code analysis tools wchich works with Visual Studio integration.

StyleCop
FxCop

These tools really helps in analysing the code and suggesting the improvements on design, localization, performance, security, naming convensions and Readability.

And also gives the report on Unused parameters in functions, Unused functions, Wrong scope (of functions, variables, enums, etc.,).

Find the list of tools for static code analysis here.

C# TimeZone Corresponding Time

In an Application (public web site) Development, TimeZone is the key if there is a time dependency for making some actions/transactions and the site is public facing across the Globe in different time zones.

TimeZoneInfo class holds the information of TimeZone properties i.e., TimeZone Display Name, TimeZone ID, All the available TimeZones and the Local TimeZone.

The below code snippet explains the real time implementation to get the TimeZone Corresponding Time.
private DateTime GetBaseDateTime(string sourceTimeZoneName)
{
  TimeZoneInfo sourceTimeZone = null;
  //loop through all the TimeZones to get source TimeZone object
  foreach (TimeZoneInfo tz in TimeZoneInfo.GetSystemTimeZones())
  {
    if (tz.DisplayName.ToUpper() == sourceTimeZoneName.ToUpper())
    {
      sourceTimeZone = tz;
      break;
    }
  }
  //TimeZoneInfo.Local gives the local timezone

  DateTime sourceTime = DateTime.MinValue;
  if (null != sourceTimeZone)
  {
    //get the source datetime based on the source timezone
    sourceTime = TimeZoneInfo.ConvertTime(DateTime.Now, sourceTimeZone);
  }
  return sourceTime;
}

Monday, March 28, 2011

Blogger Publish the Code Snippets in a Formatted View

While blogging one or more posts might need code snippet(lines of code statements) as a reference or support to the problem/solution statement.

Adding the code statements to the blog post directly renders as html where the readability might be lost.

To improve the readablity of code snippets, i recommend a nice solution which i found. The solution is simple and straight forward which can be done 3 simple steps and it allows the end-users to copy the code snippet to clipboard or get a print of that easily.

Find the detailed post here.

Friday, March 25, 2011

Magic with CSS Styling (Reverse the Full Page Text)

Type the below full STYLE tag (css elements are commented, remove comments to make it work) in any of the free text boxes and submit.
Even it works with blog post as well...

Thats it upon rendering the submitted text, the page renderes the complete html (text) in reverse order from right to left including scroll bars.

To avoid this behaviour the entered text should be encoded while submitting and should not be decoded while rendering (if decoded the page again renders the style tag instead text.

To encode the entered text use the below code statement in the business-logic.
using System.Web;
HttpContext.Current.Server.HtmlEncode(tbExtension.Text.Trim());

SharePoint Custom WebPart Load JavaScript File

To load the JavaScript file (resides in the web site or layouts folder) in a custom web part, add the below set of code statements in the CreateChildControls() method.
using System.Web.UI.HtmlControls;
protected override void CreateChildControls()
{                    
base.CreateChildControls();

string jsFilePath = "/_layouts/MyProject/MyFolder/myJsFile.js";
HtmlGenericControl jsControl = new HtmlGenericControl("script");
jsControl.Attributes.Add("type", "text/javascript");
jsControl.Attributes.Add("src", jsFilePath);
this.Page.Header.Controls.Add(jsControl);
}

SharePoint Check Current User Permissions (SPBasePermissions)

I came accross a requirement where a custom web part or page displays the Generic List fields, however hide some of the fields if the current logged-in user doesn't have edit or delete list items permission.
using Microsoft.SharePoint;
if (!SPContext.Current.Web.DoesUserHavePermissions(SPBasePermissions.EditListItems))
{ 
//hide the fields/controls which are not supposed to be shown here
}
To see the OTB available list of permissions(SPBasePermissions) have a look at the post here.

Thursday, March 24, 2011

SharePoint Update User Profile Programatically (SSP User Profiles)

Below is the code snippet to update the user profile with OTB & Custom Properties.
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;
using (SPSite site = new SPSite("http://sitecollectionurl"))
{
//User profile manager object holds the complete profile store
UserProfileManager profileManager = new UserProfileManager(ServerContext.GetContext(site));

//UserProfile object holds the acount specific userprofile
UserProfile userProfile = profileManager.GetUserProfile("domain\\administrator");

//OTB property name can be assigned as below using PropertyConstants class
userProfile[PropertyConstants.FirstName].Value = "My first name";

//Custom property value can be assigned as below by hardcoding the property name
userProfile["CustomPropertyName"].Value = "Test Value";

userProfile.Commit();
}

Loop through all the user profiles available in SSP profile store.
UserProfileManager profileManager = new UserProfileManager(ServerContext.GetContext(site));
foreach(UserProfile userProfile in profileManager)
{
if(null != userProfile[PropertyConstants.FirstName].value)
lblFirstName.Text = userProfile[PropertyConstants.FirstName].value;

if(null != userProfile["CustomPropertyName"].value)
lblCustomPropertyValue.Text = userProfile["CustomPropertyName"].value;
}

Wednesday, March 16, 2011

SharePoint Webpart Load UserControl (UserControl Webpart)

Creating a webpart to load the usercontrol instead of writing the html and business logic within the webpart itself.

Follow the below four steps to create a webpart with usercontrol.
1. Create a Asp.Net UserControl (.ascx file)
The .ascx file should inherit the code behind file as namespace.
<%@ Control Language="C#" AutoEventWireup="true" Inherits="MyProject.MyUserControls.MyClassName, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=681f114f2a212052" %>
2. Create .acsx.cs (code behind) class file as namespace for business logic
using System.Web.UI;
namespace MyProject.MyUserControls
{
public class MyClassName : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
//Code goes here...
}
}
}
3. Create a webpart

4. Load the UserControl in createchildcontrols() method.
Make sure that the .ascx file is deployed to layouts folder.
PlaceHolder ph;//placeholder to load the usercontrol
protected override void CreateChildControls()
{
ph = new PlaceHolder();
ph.ID = "profileUpdatePH";

string userControlFilePath = "~/_layouts/MyFolder/MyControl.ascx";
MyUserControls.MyClassName myControl = Page.LoadControl(userControlFilePath) as MyUserControls.MyClassName;

ph.Controls.Add(myControl);
this.Controls.Add(ph);
}

C# Get RelativeUrl from AbsoluteUrl

Getting relativeUrl from absoluteUrl is very simple.

We have a class System.Uri which takes absolute/full url as a parameter and gives the relative url.
using System;
private static string GetRelativeUrl(string fullUrl)
{
try
{
Uri uri = new Uri(fullUrl);//fullUrl is absoluteUrl
string relativeUrl = uri.AbsolutePath;//The Uri property AbsolutePath gives the relativeUrl

return relativeUrl;
}
catch (Exception ex)
{
return fullUrl;
//throw ex;
}
}

Tuesday, March 15, 2011

Microsoft SharePoint 2010 Contest

Microsoft SharePoint 2010 makes it easier for people to work together. Here‘s an opportunity to test your knowledge on Microsoft SharePoint 2010. Participate in the Quiz Contest and you stand a chance to win a Windows Mobile and USB Pen Drives.

Click here for more details.

SharePoint Webpart Custom Properties with Default Value

Most of the sharepiont custom development involves creating custom webparts. There could be scenarios where some of the values like connection string, site url, list/library name are configurable by Admin/End User and changeble depending on the requirement. To achieve this for SharePoint webpart, the values can be configured using webpart properties. Any number of webpart properties can be added to the webpart with one or more categories to differenciate. Property value can be modified/changed by modifying the shared webpart.

Webpart property default value can be set using DefaultValue property, as shown below. Note that to set the default value, the value should be stored in a constant variable, otherwise it doesn't work properly.
//Namespaces required

using System.ComponentModel;

using System.Web.UI.WebControls.WebParts;



const string const_listName = "ListName";

private string _listName = const_listName;

[Personalizable(PersonalizationScope.Shared)]

[WebBrowsable(true)]

[Category("My Category")]

[WebDisplayName("List Name")]

[WebDescription("Provide list name to get all the items.")]

[DefaultValue(const_listName)]

public string ListName

{

get

{

return _listName;

}

set 

{

_listName= value; 

}

}

Monday, March 14, 2011

SharePoint Write Custom Error to Log file (ULS Error Logging)

Most of the requirements in sharepoint applications needs custom development i.e., web parts, workflows, event recievers, timer jobs etc.,
And we might need to write the exception/error details to log somewhere(list or text file in the file sytem).

As all the sharpoint error details are logged in 12 hive Log files, even we can write our custom error details to the same log file by using the ULS logging.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
//Reference of Microsoft.Office.Server.dll needs to be added
Microsoft.Office.Server.Diagnostics.PortalLog.LogString("My Custom Error - Message:{0} || Stack Trace:{1}", ex.Message, ex.StackTrace);
});
Note: the logging code statement should be run under RunWithElevatedPrivileges, if the code is executable by end user.

Wednesday, March 9, 2011

Javascript Get Running Formatted DateTime

To show the formatted running datetime on the browser/page there is no straight way. But using javascript we can achieve this by manipulating with each unit in the datetime.

The following is the code to show the formatted running date time.
 
Html div tag to show/render the running time.

Tuesday, March 8, 2011

SharePoint PictureLibrary Thumbnail Url Vs Picture Url

I had hard time to get the complete Url of the picture as well thumbnail directly (using any property) inserad of managing with server relative/absolute url, thumbanil folder /t and the picture name.

But we have full control through SPObject Model(SPBuiltInField class) to get the picture/thumbnail Url directly.
SPList spList = web.Lists["ImagesLibrary"];
SPListItem item = spList.Items.GetItemById(itemID);

//Thumbnail Url
string thumbnailUrl = item[SPBuiltInFieldId.EncodedAbsThumbnailUrl].ToString();

//Picture Url
string pictureUrl = item[SPBuiltInFieldId.EncodedAbsUrl].ToString();
The above Urls are the full Urls of the thumbnail and picture respectively.

To get the absolute, relative Urls of the picture the Url can be managed as below.
Uri uri = new Uri(thumbnailUrl);
string relativePath = uri.AbsolutePath;