Showing posts with label MOSS. Show all posts
Showing posts with label MOSS. Show all posts

Tuesday, June 7, 2011

Querying calendar list by meeting workspace Url

Calendar list doesn't support querying the list by a workspace url making it a daunting task for finding a recurrence meeting workspace URL in Calendar list. U2U CAML editor and SharePoint views are unable to break this nut.

The trick to accomplish is to pass the relative URL for the CAML segment for querying. Following code snippet helps better understanding.

//removing the Server hostname and protocol, eg:- stripping http://Foo from http://Foo/meetingsite
string hostServer = meetingWeb.Site.Protocol + "//" + meetingWeb.Site.HostName +":" + meetingWeb.Site.Port;
searchUrl = searchUrl.Replace(hostServer, string.Empty);
SPQuery qry = new SPQuery();
qry.Query = @"<Where><Eq><FieldRef Name='Workspace' />
 <Value Type='URL'>" + SPEncode.UrlEncodeAsUrl(searchUrl) + "</Value>" +"</Eq></Where>";
qry.ViewFields = @"<FieldRef Name='Title' />
              <FieldRef Name='Location' />
              <FieldRef Name='EventDate' />
              <FieldRef Name='EndDate' />
              <FieldRef Name='fAllDayEvent' />
              <FieldRef Name='fRecurrence' />";
DataTable tbl= list.GetItems(qry); 

Sunday, June 5, 2011

CrossListQueryInfo and CrossListQueryCache gotchas

CrossListQueryInfo class which comes with the Microsoft Publishing infrastructure makes use of object caching techniques to query the requested data from the cache instead from the database. Remember to use this facility only if your code runs against a MOSS server and not on a WSS server. As this makes use of  object cache stored in WFE servers, it avoids to database input/output and network latency between the WFE's and database server.

Although it uses SPSiteDataQuery internally,the very first request using CrossListQueryCache takes more time than SPSiteDataQuery. Practically it includes the time for querying, caching and returning the values. But subsequent queries fetch results in a flash and no where comparable with SPSiteDataQuery.

Interesting fact is that this CrossListQueryCache and QueryInfo will not work in a Console line tool, it badly depends on the context. If you are really trying this interesting query technique in a web part, whenever you implement any change in your webpart and trying to debug. Apart from doing the IISReset/App pool recycle, don't forget to flush the object cache

A sample CrossListQueryCache
public DataTable GetDataTableUsingCrosslistQuery(SPSite site)
{
CrossListQueryInfo clquery = new CrossListQueryInfo();
clquery.RowLimit = 100;
clquery.WebUrl = site.ServerRelativeUrl;
clquery.UseCache = true ;
clquery.Lists = "";
clquery.Webs = "";
//clquery.Query = "";
clquery.Query = "569";
clquery.ViewFields = "";
CrossListQueryCache cache = new CrossListQueryCache(clquery);
DataTable results = cache.GetSiteData(site);
return results; 
}

Tuesday, May 10, 2011

Multiple NT authentication prompts in MOSS 2007 Server

In our team, people usually build their own development machines from the scratch and recently faced this multiple authentication prompt issue while accessing central administration right after the PSConfig wizard execution.

We tried all the browser tricks
  • switching off the IE Enhanced security configuration
  • Adding the site to IE's Local intranet zone
  • Checking the IE cookie storage setting and Authentication settings
Nothing worked, still there were multiple  authentication prompts and Fiddler showing many HTTP 401 requests. Even without providing the username and password, by pressing the ESC key continuously we were able to reach the Central administration home page. But none of the Ok/Cancel button worked as expected and leaving the Central admin console useless.

Finally Manimaran,  found a  Microsoft's KB article 95271, which clearly says you guys might be trying to install IIS 6.0 on top of a Windows Server 2003 SP2.

The machine was patched with Windows Server 2003 SP2 and we installed IIS 6.0 using an RTM disc which apparently reverted some libraries to its older version especially asp.dll. Replacing only this library didn't workout and I don't want to re-install OS Service Pack 2 again.

Workaround without re-installing Win 2003 SP2:
  • Keep Win 2003 SP1 and SP2 installation media handy in a drive.
  • Extract I386 content of these service packs using an archive tool, mine is 7zip
  • Uninstall SharePoint server and delete the content databases in database.
  • Remove the machines application server role and Uninstall IIS 6.0
  • Add Application server role , Install IIS 6.0 
  • Whenever the installer prompts for files to install point to the folder where you extracted SP2
  • In case if you don't find the files in SP2 folder, drill down in SP1 folder else in RTM disc.
Thats it now start installing SharePoint now.

Wednesday, April 20, 2011

Continuous Integration and remote deployment for SharePoint

This is a short guide of setting up a Continuous integration server and integrating with different plugins to analyse the code quality. At the end of the pipeline, we'll deploy to a remote staging server. The core idea is to build the solution on top of open source stack rather than  proprietary solutions like TFS.

Setting up Continuous Integration server:

  • Although there are tons of CI tools available in the market,as CruiseControl.Net looked for great for integrating various tools we picked up CruiseControl for our implementation.
  • Install CruiseControl.Net on a designated build server
  • CC.NET supports various source control blocks CVS,Subversion,VSS,SourceGear, StarTeam etc.
  • Download a command line client for the source control repository, for Subversion download this CollabNet Subversion command line client
  • Upon successful installation, browse to the folder C:\Program Files\CruiseControl.NET and open ccnet.config file in a text editor.
  • Add the project level detail

<project name=" testProject">
<workingDirectory>C:\develop\project1WorkingDir </workingDirectory>
</project>
  • Add source control block, which contains the SVN repository end point and credentials required to access these resources.
<sourcecontrol type="svn">
<trunkUrl>svn://Foo/trunk</trunkUrl>
<Working Directory>C:\develop\project1WorkingDir </workingDirectory>
<username>ccnet </username>
<password> ccnet </password>
</sourcecontrol>
  • Now we've added a Subversion URL with required credentials to access 
  • Let's add a Trigger block to tell the integration server at what frequency it should get latest and do a build. set the frequency as 360 seconds.
<triggers>
<intervalTrigger name="Subversion" seconds="360" buildCondition="ForceBuild" />
</triggers>
  • Add a Task block for building the solution, CC.net supports various build automation engines such as MSBuild, VSDevenv,NAnt  etc. We'll configure for MSBuild.
<tasks>
<msbuild>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe</executable>
<WorkingDirectory>C:\develop\project1WorkingDir</workingDirectory>
<projectFile>Sampleprojects.sln</projectFile >
<executable>
</tasks>
  • Alternatively if you want to use Visual studio to build the solution, following fragment will be helpful
<devenv>      
<solutionfile>C:development\Foo.sln</solutionfile>
        <configuration>Debug</configuration>
        <buildtype>Clean</buildtype>
        <executable>C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe</executable>        <buildTimeoutSeconds>360</buildTimeoutSeconds>
      </devenv>
  •  Add an Executable Task in this section after the build task for integrating other third party analysis tools like Microsoft FxCop for static code analysis, SPDisposeCheck tool for memory leak test, Microsoft StyleCop etc.
</exec>
<exec executable="C:\Program Files\Microsoft\SharePoint Dispose Check\SPDisposeCheck.exe">      <buildArgs>C:Foo\bin</buildArgs>
</exec>
  • Above Exec snippet requires all binaries to be stored in a single folder to run SPDisposeCheck, this can be done by adding a post build command in CS Project files.
  • Integrate Unit test case execution tools and code coverage tools like MSTest and NUnit test.
Package and move to staging server
  • Add a Exec task tag for WSP Builder
<exec executable="C:\Program Files\WSPTools\WSPBuilderExtensions\WSPBuilder.exe"><baseDirectory>C:\Foo\solutions</baseDirectory>      <buildTimeoutSeconds>360</buildTimeoutSeconds></exec>
  • Add a task which executes a xcopy command to move all these wsp packages to a staging server
<exec executable="C:\WINDOWS\system32\xcopy.exe">
<buildArgs>C:\Foo\Solutions\Output.WSP\*.wsp \\md-stagingSvr\share</buildArgs></exec>
Remote deployment with Sysinternal's PSExec

  • Add  another exec task to invoke PSExec tool to do the remote deployment
  • Alternatively if you have Windows Powershell in these machines you can make use of power shell to do the remote deployment.
<exec executable="C:\SysinternalsSuite\psexec.exe">
<buildArgs>\\md-stagingSvr-u "md-stagingSvr\aravind" -p 123$ "C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe" -o addsolution -filename c:\share\output.wsp</buildArgs></exec>


Tuesday, March 15, 2011

List does not exist error


While adding a new list view web part to a homepage , stuck with the following exception.
List does not exist The page you selected contains a list that does not exist. It may have been deleted by another user.
After some fiddling, found Web.Id for a LVWP is required to resolve this issue. After providing the WebId for the ListViewWebPart, web part adds to the page perfectly.

ListViewWebPart lvp = new ListViewWebPart();
lvp.ListName = Web.Lists["Tasks"].ID.ToString("B").ToUpper()  ;
lvp.ZoneID = "Center";
lvp.Title = "Tasks List";
lvp.WebId = Web.ID;  
SPFile homePage = Web.GetFile("default.aspx");
SPLimitedWebPartManager webmngr = homePage.GetLimitedWebPartManager (PersonalizationScope. Shared);
webmngr.AddWebPart(lvp, "Center", 3);
webmngr.SaveChanges(lvp);

Happy SharePointing :)

Thursday, September 17, 2009

How to find the site template used on a Site ?

Some times I stumble upon some heavily modified sites to find out the site template(Team site/Blank site etc) used for provisioning that instance. That's quite easy using the object model but I wondered is it possible through some out-of-the box tool or UI's

Recently came across the WSS RPC methods It has a function called GetProjSchema which does this magic

Authenticate with the web application

Remove all strings after the site name from the address bar and append the following string

/_vti_bin/owssvr.dll?Cmd=GetProjSchema

So if you have application as Foo and it has a site called PWA then the URL might be looking like this

http://Foo/PWA/_vti_bin/owssvr.dll?Cmd=GetProjSchema

GetProjSchema requests the CAML Schema for a Web site, this is a blend of ONET.XML for that specific site definition and some resources which are related to that provisioned site instance. This CAML schema is cached in IIS, so we've retrieved this cached version to find out the site template

This gives more details than required but we are now interested in the site template used, look at the first line "Project Title=". This is the current site template being used

A sample screen snap


Anything which comes OOTB capable of solving real world problems is good. Exploit the rendered CAML . .. .

Friday, May 22, 2009

SPHttpUtility, a hidden gem

Recently we converted a Rich text field to a plain text field in a content type which resulted in raw html tags messed up with the plain text. There are lot of options to clean a html text to a plain text. We can use Regex, a custom approach etc.

But there is an OOTB way to do it which is hidden in SPHttpUtility class. It has a method called SPHttpUtility.ConvertSimpleHtmlToText which accepts an input html string and max length of input string. This class is specific to WSS Specific Rich text field as per the documentation. Specifying -1 to the max length property will make no maximum length.

We can use this method across the site to update all metadatas to clean up the html strings

This SPHttpUtility is coming in Microsoft.Sharepoint.Utilities namespace more information can be found in MSDN

Wednesday, April 29, 2009

Move site collections between content databases using Central Admin

We can use scripted commands to move site collections across the content databases that we all are aware of, Recently I came across an astonishing hidden feature in Sharepoint adminsitration toolkit. 

Batch Site Manager, is that tool which is a hyperlink you will see after installing the toolkit to the MOSS box. This feature should be capable of doing all bulk operartions such as moving, locking and deleting site collections across content databases in a single web application as per MSDN.

Open Central Administration


clicking over the link will open up a new screen as follows and probably you will not see any site collections in the list. You will need to start the statistics aggregation timer job by clicking over "Click here" hyperlink which will populate all your site collections in this page




provide the details such as Target content database, Temporary file location and the schedule to start the job etc.



Yes, it can even send an email upon completion/Failure. So fire and forget. you can see a sample mail 



I did not check this functionality with very huge site collection move activity, if any one carried out please let me know :)

for more information go here


Thursday, November 20, 2008

Filter SharePoint List items based on User context

Filtering the items created by the logged in user can be done by simply modifying the existing View or by adding a new view which has "Created By" value = [Me].

But how to achieve the same thing in Code, Getting a list looping it and filtering the result will do. But sure performance will go down.

Here comes the CAML query for the rescue of SharePoint developer. CAML is having a token which automatically uses the current user context.

So we can write a code snippet as follows to get items created by the current user.



SPList sList=[Get the list to query here];
SPQuery query = new SPQuery();
query.Query = string.Format(
"[Where]"+
+ "[Eq]"
+ "[FieldRef Name='Author' LookupID='TRUE'/]"
+ "[Value Type='User'][UserID /][/Value]"
+ "[/Eq]"
+ "[/Where]");
SPListItemCollection listItems = sList.GetItems(query);


you will get the list items only created by the current user, no iteration, no filteration happens only clean CAML query.

Replace all square brackets[ ] with angle brackets < >. Blogger refused to accept the angle brackets.

Happy coding,

Wednesday, September 17, 2008

SharePoint development VM loves IISReset

When we develop application pages or custom web part development in SharePoint. This requires a lot of IISreset for each and every bit of change in the assembly when we are going to deploy these modified binaries GAC.

IISRESET takes a lot of time instead of that if we recycle the required application pool which is associated to our IIS web application, this will save atleast a minute of dev effort.

This recycling process can be automated by using the following OOB VB script

cscript.exe iisapp.vbs /a SharePointAppPool /r

or
cscript.exe iisapp.vbs /p [Process ID] /r

[Process ID] : This can be obtained just by executing iisapp.vbs in the command line. This will list all the application pools with their process ids

Get more info about IISapp.vbs from Microsoft Technet library

Do you want to recycle all the application pools in your IIS ?

Save the following the VB script to vbs file and replace the MachineName with your Dev machine's name

Set locator = CreateObject("WbemScripting.SWbemLocator")
Set Service = locator.connectserver("MachineName", "root/MicrosoftIISv2")
Set APCollection = Service.InstancesOf("IISApplicationPool")
For Each APInstance In APCollection
APInstance.Recycle
Next

Monday, August 4, 2008

Determine MOSS or WSS


There is no direct way to determine whether MOSS is installed over WSS throught Object model,
So we can just check the existence of profile service on the farm. Profile service comes along only with MOSS so we can ensure MOSS is installed by this snippet.


string
isapiFolder = SPUtility.GetGenericSetupPath("ISAPI");
string userProfileServicePath = Path.Combine(isapiFolder, "UserProfileService.asmx");
bool SharePointServerInstalled = File.Exists(userProfileServicePath);