Welcome to MSDN Blogs Sign in | Join | Help

Ram's Blog

Blogging about SharePoint experiences
Neat little technique to link build number from build server to assembly file version

I’m sure you guys can probably relate to this, you check in a fix and tester comes back to you and says it still doesn’t work and you are like what the hell it works on my machine, after some digging you find the correct binaries did not get deployed

Just wanted to show you a neat little thing we implemented to link build number from build server to assembly file version

Add a new “AssemblyInfo.cs” file to your source folder of your solution and name it “SharedAssemblyInfo.cs”

Add the Assembly file version attribute to this file and add this file as linked file to all your projects within your solution

[assembly: AssemblyFileVersion("1.0.0.0")]

Next step is setting the AssemblyFileVersion attribute with build number value from build server in msbuild script before projects are built.

<PropertyGroup>

    <AssemblyFileVersion Condition="'$(BUILD_NUMBER)' != '' ">$(BUILD_NUMBER)</AssemblyFileVersion> <!-- make sure in teambuild this parameter is set as build arguments -->

</PropertyGroup>

<Target Name="SetAssemblyFileVersionWithBuildNumber">
    <WriteLinesToFile File="$(SrcDir)\SharedAssemblyInfo.cs" Lines="[assembly:AssemblyFileVersion(&quot;$(AssemblyFileVersion)&quot;)]" Overwrite="true"/>
  </Target>

Technorati Tags: ,
Things you should know when using silverlight in SP2010

We have been using Silverlight heavily in my current SP2010 project and here are the things you should know when using silverlight in SP2010 sites

  • SL Webpart does not load in IE 64bit, be sure to browse the site in IE 32 bit mode
  • SL Webpart did not load in Safari on Mac, Safari on Mac is supported but Safari on PC is not (unfortunately Safari on PC works fine)
  • Don’t hard code the xap path in SL webpart. I learned this the hard way, always use relative path because if you extend the web application to a different zone and you are accessing the site through a different zone url. SL webpart will fail to load if you hard code full path.
  • Deploying xap files, you have a choice to create a document library and upload xap. We chose to deploy to “ClientBin” directory under layouts as it was easy to do with VS 2010 and rich sharepoint support available in VS 2010
  • WCF proxy generation gave major head aches in VS 2010 for Silverlight projects, after you update the WCF service and try to update the service reference in SL project, proxy generation would fail and no proxy classes gets generated. They way I got this working is by reflecting existing WCF services deployed to SharePoint and looking at web.config settings
Technorati Tags: ,,
Supported way of replacing application pages in layouts directory

In SharePoint 2010 the CustomPages dictionary allows you to replace AccessDenied, Confirmation, Error, Login, RequestAccess, Signout, or WebDeleted pages by supplying an alternative path to a different file in the layouts directory. 

You can access the CustomPages dictionary both through OM and through PS cmdlet. This would be the supported way of replacing these pages in layouts directory.

2 CmdLets that you might want to check it out

  • Get-SPCustomLayoutsPage (Will display the collection, you can selectively look at specific item by specifying parameter –Identity “AccessDenied | Confirmation | Error | Login | RequestAccess | Signout | WebDeleted
  • Set-SPCustomLayoutsPage

Following PS Command replaces Request Access Page (reqacc.aspx) in layouts folder, assuming customized version of Request Access page is deployed to custompages folder under layouts directory

Set-SPCustomLayoutsPage -Identity "RequestAccess" -Rela
ivePath "/_layouts/custompages/reqacc.aspx" -WebApplication "{replace with web app url}"

 

Technorati Tags:
Native VHD BOOT ISSuE “Application missing”

So I ran into an issue while setting up native VHD boot into a windows server 2008 r2 server, native VHD boot just wouldn’t work when I place the VHD onto my additional (bigger & faster) hard drive that is sitting on a ultrabay, If you’ve got a t61 I recommend getting one and swapping out the dvd drive with ultrabay which will allow you to add an extra drive for those VHD’s.

All my existing VHDs that is sitting on main disk works fine for native VHD boot, but the ones on Ultrabay hdd did not.

After some hrs of searching internet and pulling my hair, I figured out the reason for this was my HDD on ultrabay was excluded from the boot devices list, added it to boot devices list and it worked like a charm.

As far as setting up native VHD boot I recommend following the screencast by Keith Combs

 

Getting intellisense when editing bdc application definition files in vs2008

if you are having trouble getting intellisense like I did with VS 2008 here are the steps that you can take

download the bdcmetadata.xsd from following url and copy the file to “c:\program files\Microsoft Visual Studio 9\xml\schemas” directory (assuming VS was installed on “c:\program files\microsoft visual studio 9” directory)

Remove the “xsi:schemalocation” attribute from the root node of your application definition file, if one does exist

Restart Visual Studio

Annoying SQL Server 2008 behavior

In SQL Server management studio when you try to save changes after altering table you might experience an error message that says something like “saving changes not permitted. The changes you have made require following tables to be dropped and re-created. You have either made changes to a table that can’t be re-created or enabled the option prevent saving changes that require the table to be re-created”

Basically if you make following changes

  • Allow Null setting
  • Re-ordering columns in table
  • Change column data type
  • Add a new column

This will cause a table drop and re-create and by default since “prevent changes that require table re-creation is turned on” which is a good thing as above operations can cause data loss, you won't be able to save your changes.

This can be annoying when you are developing on your workstation, workaround is to use Alter table scripts or turn off the option in SQL management studio

If you are turning off the option in SQL management studio be aware of the risks associated for ex. data loss

Instruction to turn off “Prevent changes that require table re-creation” option

Click on option menu under tools

sqlblog1

Un-check “prevent saving changes that require table re-creation” option

sqlblog2

Following support article has more information on the issue

 

Technorati Tags: ,
My MCM experience

This is sort of a delayed post but its better late than never right? In March I got to attend MCM SharePoint R2 rotation in Seattle Washington along with I guess 16 other SharePoint peeps mostly internal full time MS employees and a handful of partners and MVP’s. There has been couple of really good posts on MCM experience by Spence, Maurice, and others so I’m not going to repeat some of the things you may have already heard, hopefully this post will give you some additional perspective.

 

Things you should do before you start your MCM training

  • You will get a very comprehensive list of pre-read, make sure you read through as much material as you can, sometimes this can be very hard especially in my case I was in the middle of the project and couldn’t get through many items in the pre-read list.
  • Make arrangements to stay in corporate housing (ABODA) and if you can share with another candidate it can work out very affordable, especially external folks. Additionally you can pick up your favorite vegetables/meat or what ever from grocery store and cook your meal instead of eating out everyday. There is also an ok gymn.
  • Depending on the time you are in Seattle get a good understanding of what the weather is like around that time, ask the MCM coordinators about weather and make sure you come prepared. In my case I was there in March and pretty much rained every day, I’m an avid runner, I didn’t bring my rain gear and couldn’t run outside, so I basically had no runs the entire 3 weeks I was there. Really threw my schedule off
  • Be prepared to be in Seattle entire 3 weeks that means no travelling back on weekends.

During the training

  • Take advantage of the Infrastructure available for you, for ex MCM team provides every candidate a server environment with 16GB ram and plenty of hard drive space for all those VMS, there is also pre-configured farms available for HOL and anything else you may want to work on. I stayed late most of the days to work on some infrastructure type of things that you probably won’t do much, for ex things like configuring log shipping, mirroring, ADFS setup etc
  • Learn as much as you can, I can remember last time I was in a similar environment was back in college, you won’t get opportunity like this to dedicate entire time purely for learning and not being bugged by your wife and kids :)
  • Stick to a good balanced schedule, and take advantage of networking opportunities (Get together at BLDG 16 was cool, I enjoyed my conversations with Brion Stone (Mr. Search) and others
  • Last but not least “HAVE FUN” Seattle definitely has some good restaurants around, I personally loved the Malaysian Restaurant and the Vietnamese PHO, then there is also Udupi Palace a South Indian vegetarian restaurant (I’m originally from South India so finding this place really made my day). <update>Don’t drink and drive, Spence and I almost had our mug shots taken, got pulled over after few drinks and it was my confident “no sir I did not have any drinks that saved the day” :) </update>

I haven’t passed MCM yet, but I’m confident I will soon. If I were to do it all over again I would probably spend more time reading through pre-read, like I said I was in the middle of project with 3hr commute everyday, was just too much for me to have any kind of time to go through all the pre-read, had to work my behind off 3 weeks I was there. Also I would read the QUAL lab instructions bit more thoroughly I ended up working on wrong farm and lost lot of time troubleshooting, there is just way too much stuff to do so you can’t waste any time troubleshooting

Lastly my congrats to all 6 that passed first try, I know it is not a walk in the park, so I tip my hat off to them and my best wishes to future candidates and there is no better feeling to do it first shot.

<update>

I’m now MCM for SharePoint 2007

</update>

Peace

</Ram>

Technorati Tags: ,
showing items saved to My links on sharepoint site filtered by group

I’m working on a Search oriented portal using FAST search, one of the requirements we have is the ability to save currently executed search so users can re-run the search at a later point of time. We wrote a custom web part that leverages “My Links” to save the search query URLs. We needed to display all the saved searches in “My Links” in a web part page within Sharepoint site, so I started looking at QuickLinksMicroView webpart to accomplish this. Incase you guys are not familar with QuickLinksMicroView webpart, if you try to add this webpart to the page you won’t find it, you have to go to webpart gallery add it to the gallery and then you should be able to insert to page. This worked great to a certain extent, problem was as users started adding other links to “My Links” obviously it started to show up in the webpart and we needed to have a filtered view of this to show just the links grouped under “My Searches” group. Unfortunately QuickLinksMicroView webpart had no way of achieving this filtered behavior we needed. In this post I will walk through how you can use dataview and user profile webservice with bit of custom XSLT to show items from “My Links” filtered by group

Insert Dataview webpart, for data source expand xml web services and click on “connect to a web service” link

showquicklinks1

This will bring up the data source properties window, enter user profile web service URL, from operation dropdown list of select “GetUserLinks” and click on ok to close the data source properties

showquicklinks2

After inserting the data view on to the page, from the common data view tasks menu click on parameters

showquicklinks3

 

 

In the Data View Parameters define 2 new parameter binding, one for current user, source for this parameter will be “AUTH_USER” “Server Variable” and the other one will be used for filtering data view to show only items in a specific group, source for this parameter will be query string

showquicklinks4

showquicklinks5

Next task is to define a filter for the data view, to do this from the common data view tasks select filter option

showquicklinks6

In the filter criteria dialog box define filter clause, from the field name dropdown select “Group” and for Value select “LinkGroup” parameter which we defined earlier.

Click on ok to close out the filter criteria dialog. Now we are ready to test this data view webpart

showquicklinks7

For the purpose of demo I saved bunch of links to “My Links”

showquicklinks8

View below shows “My Links” for group “General”. When the parameter was defined I used “General” for default value

you can change this to different value to meet your needs.

showquicklinks9

View below show “My Links” for group “Best Bets”, group is passed via query string as shown in screen print

showquicklinks10

I also modified the XSL contained within the dataview web part to customize rendering. Hope this was useful, Email me if you are interested in an export of the data view webpart.

implementing a simple Cross SIte collection list view webpart

Out of the box list view web part does not support lists that are contained in a different site collection. In this post I will show you how you can write a simple web part that will allow cross site collection list support.

Within the custom web part I’m leveraging ListViewByQuery control that is contained within the “Microsoft.SharePoint.WebControls” namespace in assembly “Microsoft.SharePoint.dll”

Couple of things about “ListViewByQuery” control

  • you must set “List” and “Query” properties for this control
  • You will get a “missing list” exception or something like that if you don’t set “ViewFields” property for the Query
  • SPQuery should be instantiated with a View, otherwise you will get a blank page (If you instantiate SPQuery with a view you do not need to specify “ViewFields” property although MSDN documentation states different)

My custom web part has following properties defined

SiteUrl: if the list is in different site collection, set site collection URL

ViewName: List View Name to be used

SourceList: Source List to Query

In the overriden CreateChildControls method of web part new up an instance of “ListViewControl” and set List and Query properties and add to the controls collection. If a site url was not specified, we assume the list is contained within the current web context, also if a view name was specified through properties, we are using that when creating SPQuery object, other wise default view on the list is used.

 

   1: protected override void CreateChildControls()
   2: {
   3:     base.CreateChildControls();
   4:     SPSite site = null ;
   5:     SPWeb web = null ;
   6:     Boolean disposeSPSite = false ;
   7:     try
   8:     {
   9:         if (this.SourceList != string.Empty && this.SourceList != string.Empty)
  10:         {
  11:             viewByQuery = new ListViewByQuery();
  12:             if(this.SiteUrl != null && this.SiteUrl != string.Empty)
  13:             {
  14:                 site = new SPSite(this.SiteUrl);
  15:                 disposeSPSite = true ;
  16:             }
  17:             else
  18:             {
  19:                 site = SPContext.Current.Site ;
  20:             }
  21:             web = site.OpenWeb();
  22:             SPList sourceList = web.Lists[this.SourceList];
  23:             viewByQuery.List = sourceList;
  24:             SPQuery query = null;
  25:             if (CheckIfViewExists(viewByQuery.List))
  26:             {
  27:                 //use the view specified in webpart property
  28:                 query = new SPQuery(viewByQuery.List.Views[this.ViewName]);
  29:             }
  30:             else
  31:             {
  32:                 //use default view to initialized
  33:                 query = new SPQuery(viewByQuery.List.DefaultView);
  34:             }
  35:             viewByQuery.Query = query;
  36:             viewByQuery.DisableFilter = this.DisableFilter;
  37:             viewByQuery.DisableSort = this.DisableSort;
  38:             this.Controls.Add(viewByQuery);
  39:         }
  40:         else
  41:         {
  42:             encodedLiteral = new EncodedLiteral();
  43:             encodedLiteral.Text = "This webpart is not configured.";
  44:             this.Controls.Add(encodedLiteral);
  45:         }
  46:     }
  47:     finally
  48:     {
  49:         if(disposeSPSite)
  50:         {
  51:             ((IDisposable)site).Dispose();
  52:             ((IDisposable)web).Dispose();
  53:         }
  54:     }
  55: }

Custom Web Part Configuration View

crosssistelist3

Here is a view of the web part showing documents from document library named “Documents” contained within a different site collection

crosssitelist4

All Items view of document library named “Documents” in root site collection of the web app

crossitelist1

Code from web part project, if you find it useful please leave a comment here…

   1: #region using statements
   2: using System;
   3: using System.Runtime.InteropServices;
   4: using System.Web;
   5: using System.Web.UI;
   6: using System.Web.UI.WebControls;
   7: using System.Web.UI.WebControls.WebParts;
   8: using System.Xml.Serialization;
   9: using System.Text;
  10:  
  11:  
  12: using Microsoft.SharePoint;
  13: using Microsoft.SharePoint.WebControls;
  14: using Microsoft.SharePoint.WebPartPages;
  15: #endregion
  16:  
  17: namespace Foo
  18: {
  19:     [Guid("9558189B-CD3B-481b-9B06-AE434CF47B18")]
  20:     public class CrossSiteCollectionListViewWebPart : System.Web.UI.WebControls.WebParts.WebPart
  21:     {
  22:         #region protected child control variable definitions
  23:         protected ListViewByQuery viewByQuery = null;
  24:         protected EncodedLiteral encodedLiteral = null;
  25:         #endregion
  26:         
  27:         #region webpart properties
  28:         /// <summary>
  29:         /// 
  30:         /// </summary>
  31:         private string viewNameField = string.Empty;
  32:         [Personalizable(), WebPartStorage(Storage.Shared), WebBrowsable(),
  33:          WebDisplayName("View Name"), WebDescription("View Name")]
  34:         public string ViewName
  35:         {
  36:             get
  37:             {
  38:                 return this.viewNameField;
  39:             }
  40:             set
  41:             {
  42:                 this.viewNameField = value;
  43:             }
  44:         }
  45:         private string siteUrlField = string.Empty;
  46:         [Personalizable(), WebPartStorage(Storage.Shared), WebBrowsable(),
  47:          WebDisplayName("Site Url"), WebDescription("Site Url")]
  48:         public string SiteUrl
  49:         {
  50:             get
  51:             {
  52:                 return this.siteUrlField;
  53:             }
  54:             set
  55:             {
  56:                 this.siteUrlField = value;
  57:             }
  58:         }
  59:         /// <summary>
  60:         /// 
  61:         /// </summary>
  62:         private string sourceListField = string.Empty;
  63:         [Personalizable(), WebPartStorage(Storage.Shared), WebBrowsable(),
  64:          WebDisplayName("Source List"), WebDescription("Source list to query")]
  65:         public string SourceList
  66:         {
  67:             get
  68:             {
  69:                 return this.sourceListField;
  70:             }
  71:             set
  72:             {
  73:                 this.sourceListField = value;
  74:             }
  75:         }
  76:         private Boolean disableFilterField = false;
  77:         [Personalizable(), WebPartStorage(Storage.Shared), WebBrowsable(),
  78:          WebDisplayName("Disable Filter"), WebDescription("Disable List Filtering")]
  79:         public Boolean DisableFilter
  80:         {
  81:             get
  82:             {
  83:                 return disableFilterField;
  84:             }
  85:             set
  86:             {
  87:                 disableFilterField = value;
  88:             }
  89:         }
  90:         private Boolean disableSortField = false;
  91:         [Personalizable(), WebPartStorage(Storage.Shared), WebBrowsable(),
  92:          WebDisplayName("Disable Sort"), WebDescription("Disable list sorting")]
  93:         public Boolean DisableSort
  94:         {
  95:             get
  96:             {
  97:                 return disableSortField;
  98:             }
  99:             set
 100:             {
 101:                 this.disableSortField = value;
 102:             }
 103:         }
 104:         #endregion
 105:  
 106:         #region overrides
 107:         protected override void CreateChildControls()
 108:         {
 109:             base.CreateChildControls();
 110:             SPSite site = null ;
 111:             SPWeb web = null ;
 112:             Boolean disposeSPSite = false ;
 113:             try
 114:             {
 115:                 if (this.SourceList != string.Empty && this.SourceList != string.Empty)
 116:                 {
 117:                     viewByQuery = new ListViewByQuery();
 118:                     if(this.SiteUrl != null && this.SiteUrl != string.Empty)
 119:                     {
 120:                         site = new SPSite(this.SiteUrl);
 121:                         disposeSPSite = true ;
 122:                     }
 123:                     else
 124:                     {
 125:                         site = SPContext.Current.Site ;
 126:                     }
 127:                     web = site.OpenWeb();
 128:                     SPList sourceList = web.Lists[this.SourceList];
 129:                     viewByQuery.List = sourceList;
 130:                     SPQuery query = null;
 131:                     if (CheckIfViewExists(viewByQuery.List))
 132:                     {
 133:                         //use the view specified in webpart property
 134:                         query = new SPQuery(viewByQuery.List.Views[this.ViewName]);
 135:                     }
 136:                     else
 137:                     {
 138:                         //use default view to initialized
 139:                         query = new SPQuery(viewByQuery.List.DefaultView);
 140:                     }
 141:                     viewByQuery.Query = query;
 142:                     viewByQuery.DisableFilter = this.DisableFilter;
 143:                     viewByQuery.DisableSort = this.DisableSort;
 144:                     this.Controls.Add(viewByQuery);
 145:                 }
 146:                 else
 147:                 {
 148:                     encodedLiteral = new EncodedLiteral();
 149:                     encodedLiteral.Text = "This webpart is not configured.";
 150:                     this.Controls.Add(encodedLiteral);
 151:                 }
 152:             }
 153:             finally
 154:             {
 155:                 if(disposeSPSite)
 156:                 {
 157:                     ((IDisposable)site).Dispose();
 158:                     ((IDisposable)web).Dispose();
 159:                 }
 160:             }
 161:         }
 162:         protected override void RenderContents(HtmlTextWriter writer)
 163:         {
 164:             
 165:             EnsureChildControls();
 166:             RenderChildren(writer);
 167:         }
 168:         #endregion
 169:  
 170:         #region helper methods
 171:         private Boolean CheckIfViewExists(SPList list)
 172:         {
 173:             Boolean ret = false;
 174:  
 175:             foreach (SPView view in list.Views)
 176:             {
 177:                 if (view.Title.ToLower() == this.ViewName.ToLower())
 178:                 {
 179:                     ret = true;
 180:                 }
 181:             }
 182:             return ret;
 183:         }
 184:         #endregion
 185:     }
 186: }
Technorati Tags: ,
Sharepoint considerations when configuring AD rights management cluster

By default AD Rights Management cluster certificate pipeline ACL is configured to allow only local system account. All the web front end servers in your SharePoint farm must be granted read and execute permission. In addition IIS application pool account and Server Farm account also need read and execute permission assigned

Logon to RMS server

Navigate to C:\Inetpub\wwwrot\_wmcs\Certification.

Right-click ServerCertification.asmx, click Properties, and then click the Security tab.

Click Advanced, click Edit, select the Include inheritable permissions from this object’s parent check box, and then click OK twice.

image

Click Add

Click Object Types, select the Computers check box, and then click OK.

Add the web front end server and assign read/execute and read permissions

Repeat the above steps for all web front ends in your farm, server farm account and application pool account.

From the command prompt run “iisreset /noforce”

You are now ready to integrate MOSS with AD RMS

SOME TIPS FOR developing on windows server 2008

If you are a SharePoint developer developing on windows server 2008, I’m pretty sure you share my frustration. Here is some things you might want to configure in your development workstation.

Debugging your Visual Studio project by attaching to w3pwp process requires you to run Visual Studio as administrator. Here is steps you can perform to automatically run Visual Studio as administrator.

Create a shortcut to Visual Studio 2008 on your desktop. From the VS shortcut properties click on “Advanced” Button

win2k8dev1

Check Run as Administrator Checkbox

win2k8dev2

In IIS 7 health monitoring pinging is turned on by default and every 30 seconds IIS 7 sends out health monitoring pings. If a response is not received from worker process after the time limit is exceeded WWW service will terminate the worker process. When you are debugging code in VS by attaching to w3wp worker process, terminating worker process is not a good thing :), either increase the time limit or Turn off health monitoring pinging all together. You can go into application pool advanced settings to change the health monitoring ping settings

win2k8dev3

I also found following blog posts very helpful

ACCESS and KERBEROS Enabled sharepoint sites

This past week I found out that Edit In data sheet component of access which is used in SharePoint list and also adding SharePoint list as link table to query or perform bulk edits to list does not work if your SharePoint site is configured for Kerberos Authentication. I was able to get hold of some internal SP2 bits, planning on testing to see if there is any fixes

Technorati Tags: ,
missing in action

Man its been a while since my last post. I have been crazy busy since end of February, started new project which makes me drive 1.5 hrs each way (prefer out of town traveling jobs) and then in March was out in Seattle for 3 weeks for SharePoint Master training (if you get a chance, do it). now back on project. Between about 3 hr commute and work, not really finding too much time to blog.

IE Developer toolbar

This is definitely a must have have tool for every one who is involved with branding SharePoint sites, My favorite feature, find element by click. This allows you to click on any part of the page and the DOM browser will highlight the element allowing you to see the style. Really cool tool for sharepoint branding to figure out all the css classes

go download from here and check it out if you haven’t

Sharepoint javascript utilities

I posted my sharepoint javascript utilities to msdn code gallery site, it contains re-usable methods for getting sharepoint list data, getting list schema information, etc from client. Also has a dropdownloader JS Object that you can instantiate and use LoadDropDown method to bind an HTML select control to sharepoint list.

Go get it from here http://code.msdn.microsoft.com/SPListJS

More Posts Next page »
Page view tracker