Tuesday, 3 September 2013

How to check if a SPWeb exists within a SPSite


SharePoint objects get bit tricky when it comes to check if an objects exists or not specially in SharePoint 2007. Today I came across a situation where I had to check if a web exists or not, so I tried using this code,


using (SPSite site = new SPSite("https://myPortal.myCompany.com/Sites/SubSites/DoesnotExistsSite"))
using (SPWeb web = site.OpenWeb())
{
         if(web.Exists)
                //Do this
}


Above code complied perfectly and didn't threw any error at all, however it didn't worked as I was expecting an error e.g. "Web doesn't exists". So I did realized you give any address to SPSite() method it will try to get site collection object regardless of full URL provided exists or not, okay it's something that might does makes sense, but when it tries to open web using OpenWeb() method, it should open the web URL has been provided to, for example this URL,

https://myPortal.myCompany.com/Sites/SubSites/DoesnotExistsSite

It will opens SubSites web, and if URL is 

https://myPortal.myCompany.com/Sites/SubSites/DoesnotExistsSite/alksjdalskdjaslkdjaskldjasldjasld

It still opens up SubSites as SPWeb object.

I was expecting it to throw an error however it didn't so I got "true" for web.exists.

I did some research and figured out another way to find out if SPWeb actually exists for supplied URL or not,


public static void DoesWebExists()
{
       string tempUrl = "https://myPortal.myCompany.com/Sites/SubSites/DoesnotExistsSite/alksjda";
       Uri u = new Uri(tempUrl);

       using (SPSite site = new SPSite(tempUrl))
       using (SPWeb web = site.OpenWeb(u.AbsolutePath.ToString(), true))
       {
              Console.WriteLine(web.Exists);
       }
}


Above example has been tested and works fine as far as SPSite object exists for provided Url.

How to check Assembly related errors using Fusion Log utility


One of most annoying exceptions we developer get is assembly found doesn't match with loaded assembly, even though we put right assembly in GAC. There can be tens of reason as why assembly loaded doesn't match and that's where fusion log utility helps.

In order to use this utility you need to have installed Microsoft SDKs or it gets installed when you installed visual studio. I have installed Visual Studio 2008 on Windows Server 2003 so my guide will be based on it.

Open Visual Studio 2008 command prompt and navigate to directory

C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin>

Now type fuslogvw.exe and you will see a windows appears as shown below,




Click on settings and check box Log all binds to disk as shown, you can also select "Custom log path" but make sure directory exists.

If your log was disabled before then you might need to do a IIS reset to make it start working. (it took mine around 30 minutes to pick up errors because of unknown reasons).

You will see logs as shown in picture below,


And clicking on any log will open it in browser as it's a html file, as shown below.



Make sure to disable log afterwords as otherwise they will take a lot of space within short time.

How to return Primary Key of just Inserted record into SQL Datatable using Strongly Typed DataSet

Inserting data directly into SQL data table isn't recommended because of security reasons, which is why most of us use Strongly Typed data-sets, it provides our solution with a secured layer to interact with database, enhancing security.

Saying that strongly data-sets are better way of interacting with database but they can sometime become hectic and consume time while debugging them specially when you use TableAdapter Query Configuration Wizard as it doesn't always configures your data-sets the way they should be.

Back to problem SCOPE_IDENTITY() not returning right value, as we use it to return the primary key generated by table when we try to insert some records into the specified table. Most of us simply use return SCOPE_IDENTITY() as it works sometimes and on some servers but it doesn't work other times (and that's when debugging takes ages).

Best way I recommend of getting back primary key of inserted record is by using OUTPUT Parameter in your stored procedure as it will make sure your strongly typed data-set get's the right value.

Here's an example of how your Stored Procedure for inserting a record should look like,

USE [DataBaseName]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE procedure [dbo].[StoredProcedureName]
(
          @ColumnA int,
          @ColumnB int,
          @NewID int
 )
AS

INSERT Into tableName
Values
(
          @ColumnA,
          @ColumnB
 )
SELECT @NewID = SCOPE_IDENTITY()

In this article I will assume you already know how to create a data-set or have it ready, but if you don't know then you can find instructions at How to Create a DataSet ?.

Once your data-set is ready just drag and drop table or stored procedure into designer class from Server Explorer. Now if you drag and drop table which I would recommended you  can add a query and select your stored procedure using TableAdapter Query Configuration Wizard. Thing that you need to take care of is to select

"A Single Value - A typed function will be...."

Then name your stored procedure as you desire and finish the wizard. Your method will look something like this,

public int InsertDataMethod(solution.myRow details)
{
      int? output = 0;
      TableName_TableAdapter tableAdapter = new TableName_TableAdapter();
      using (tableAdapter.Connection = new SqlConnection(ConnectionString))
      {
         tableAdapter.StoredProcedureDataSet(details.ColumnA, details.ColumnB, ref output);
       }
       return Convert.ToInt32(output);
}


Make sure dataset's ExecuteMode property is Scalar otherwise it might doesn't return right ID.

Thursday, 8 August 2013

Preventing multiple events from triggering when adding a list item or document to a SharePoint list

Normally what happens is developer's use both Item Added and Item Updated events when they want to execute some specific code across just added list item, in result multiple list events triggers.

For example when a user adds a document to a document library first event triggers is Item Added when document is added to list, whereas second event occurs when user is forwarded to /Forms/EditForm.aspx?Mode=Upload  and user can change item's meta data.

You can prevent it by checking if added item is changed after being added to library/list or not using SPItemEventProperties.Versionless property.

For example (SharePoint 2007):

    class myEventReceiverClass: SPItemEventReceiver
    {
        public override void ItemUpdated(SPItemEventProperties properties)
        {
            try
            {
                this.DisableEventFiring();

                // Only Execute if item hasn't been changed in edit form
                if (!properties.Versionless)
                    ExecuteMyCode(properties);
            }
            finally
            {
                this.EnableEventFiring();
            }
        }
    }


For SharePoint 2010 and 2013 it is recommended to use EventFiringEnabled for getting and setting event firing as shown in example below;

         public override void ItemUpdated(SPItemEventProperties properties)
        {
            this.EventFiringEnabled = false;
            properties.ListItem.Update();
            this.EventFiringEnabled = true;
        }

Wednesday, 17 July 2013

How to check error's on K2 Black Pearl working in a SharePoint environment


When you deploy processes to K2 Black Pearl workflow server you can check process state as what stage it is on and if there's any error.

In order to view flow of process follow steps below,
  • Open Internet explorer on your K2 BP workflow server and navigate to this URL given below,

    http://ServerName/workspace/Navigation/Navigation.aspx
  • Make sure you use the right Server Name, once the page is loaded, click on Process Overview on left navigation as shown in picture below,


  • Now if you click on any process in Process Name column, it will take you to Process Instances window as shown in screenshot below. On this window you will be able to see some details about every single processes that has been initialized whether using ASP.NET application forms or a though a SharePoint web part. You are able to see who originated this process or if it's still running or complete.



  • If something go wrong then process instance will be in error state and it's process status will be "Error". You can view process flow by clicking on image within orange box in screenshot above. It will exactly show you place where process stopped. In K2 BP you can do Real Time Monitoring which isn't available in K2 2003 work-space. Real Time Monitoring will update process workflow without need of refreshing page again and again. Screenshot below showing example workflow,




  • If you want to see data related to process instance e.g. Data or XML fields then go back to previous page and click on it's Process's Folio e.g. Empty Folio in this case, you can set process instance's folio in process to be more specific e.g. have some title or id instead of Empty Folio. Clicking on process instance Folio will display further details e.g. Activity Name, Status, and then Duration which is a great feature for monitoring performance. An example screenshot is shown below,





  • Further clicking on Data in above screenshot will display data fields and there values, same with XML Data as it will display XML data that we may had used. Further clicking on Activity Name will display Event Name that are within that specific Activity. It will provide same details for events as we get for activities and an extra Destination which can be a role or activity.
  • K2 Black Pearl logs all errors that come up while running a process instance, you can view all processes errors by going to,

    >> Management ( Top Navigation Tab) >> Management Console >> K2 Black Pearl Server (Left Navigation Tab) >> WorkFlow Server >> Error Profiles >> All



  • You can also add new error profiles as if you have 10's of processes and you want to see errors related to a specific process only. Once you see the error, you can take steps you need to fix it.
  • After fixing the issue you can click on Retry to assume process from where it was stopped but sometimes you need to modify K2 black pearl process and redeploy it to see the changes. Check my blog post for how to deploy K2 BP process.
Note: Some of the screenshots used in this article has been picked up from Google search.

Thursday, 4 July 2013

Deploying K2 Black Pearl Project to INT or Production


Developing and deploying K2 black pearl on a development machine doesn't take a lot of effort but just few clicks, however when you want to deploy project to integration or production server you will need to create a deployment package. Once you get deployment project files you can use MSBUILD.exe to deploy it on Production server.

You can also deploy it remotely to production server as far as you are trying to deploy it within domain and port 5555 is enabled to communicate with other servers as other wise you will get connection refused or lost errors while deploying.

Follow steps below to create a package using Visual Studio 2010 and deploy it on Integration server with just K2 Black Pearl on it using MSBUILD,


  • Build your project so that you get the latest DLLs in your debug or release folder.



  • Right click on project and then click on "Create Deploy Package" as shown in picture below, you only get this option if you would had installed K2 BP extension for Visual Studio 2010.





  • Above steps will create a deployment package at directory,

    Directory To Your Project\Project Folder Name\Project Process Files\obj\Release
    //if your build is release then deployment project will be created or updated in release folder


  • Release folder has all the files you need for deployment so take it your K2 BP production server (with K2 BP already installed on it) and open Visual Studio command prompt or check this post out to see how to open VS command prompt.
  • Execute following commands one by one to deploy package to server,

    cd C:\Windows\Microsoft.NET\Framework\v2.0.50727

    MSBUILD "C:\Users\deploymentAccount\Desktop\Release\Deployment\myDeploymentFile.msbuild" /p:Enivronment=INT



Now if you receive this error,

Build FAILED.
C:\Users\deploymentAccount\Desktop\Release\Deployment\myDeploymentFile.msbuild(235,5): error : SmartObject Server Exception: Could not publish SmartObject Definition to server: Error refreshing Service Instance 'WorkflowReportingService'. Service returned : 'Workflow Reporting SO Service: MSDTC on
 server 'Database Server' is unavailable.
C:\Users\deploymentAccount\Desktop\Release\Deployment\myDeploymentFile.msbuild(235,5): error : '.
C:\Users\deploymentAccount\Desktop\Release\Deployment\myDeploymentFile.msbuild(235,5): error : . SmartObject: [My Project (20) Process Instances]
C:\Users\deploymentAccount\Desktop\Release\Deployment\myDeploymentFile.msbuild(235,5): error :
0 Warning(s)
1 Error(s)


Then remove following lines from file with MSBUILD extension in your deployment folder only if you didn't used smart objects,

    <Create_Workflow_SmartObjects>True</Create_Workflow_SmartObjects>
    <Create_Workflow_Reporting_SmartObjects>True</Create_Workflow_Reporting_SmartObjects>

In our environment, we are not using smart objects but while creating deployment package it just adds above lines and while deploying errors, so removing above lines result in successful deployment.

Wednesday, 19 June 2013

Convert WSDL file to a C# class and then DLL


Today I was trying to update a web reference of custom web services in my project but because of some reason visual studio 2010 wasn't getting the latest methods I added even though I could see them using browser. Hence to get around problem I converted WSDL file into C# class and then into a dll.

You can target dll to any framework you would like. In order to get DLL in .Net 4.0 framework try following steps;

For getting you library dll in.Net 4.0 framework you will require Visual Studio 2010 tools installed on your machine, however for it in .Net 3.5 framework you will need Visual Studio 2008.


  1. Open Visual Studio Command prompt as a administrator by going to Start menu > All Programs > Microsoft Visual Studio 2010 > Visual Studio Tools > Visual Studio Command Prompt (2010).
  2. Put your WSDL file in somewhere accessible e.g. in this case I will put it in my C drive and getting output CS class in C drive too but you can change it. Type this command and press okay,

    C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>wsdl /l:C# /out:C:\OutPutClassName.cs C:\myWebService.wsdl
  3. Above command will generate a CS class in your C drive, now if you want to convert this class into dll in .Net 4.0, type this command;

    C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>csc /target:library /r:System.Data.dll /r:System.Data.Services.Client.dll /out:C:\OutPutClassName.dll C:\OutPutClassName.cs

    Above command will get you class library dll in .Net 4.0 framework.
  4. In order to get ..Net 3.5 use this command,

    C:\Program Files\Microsoft Visual Studio 9.0\VC>csc /target:library /r:System.Data.dll  /out:C:\OutPutClassName.dll C:\OutPutClassName.cs
MSDN Reference: http://msdn.microsoft.com/en-us/library/bb332338.aspx#msdnwcfhc_topic6