Friday, 10 April 2015

AppFabric Command

This are a list of useful command that I've gathered while developing custom web part under SharePoint 2013. This is a distributed cache services command and I've developed my custom web part to use this services. I'm aware that Microsoft didn't support custom development against this distributed cache services. But I need a simple cache solution to support our custom application under SharePoint farm.

​Remove Distributed Cache

Stop-SPDistributedCacheServiceInstance -Graceful
Remove-SPDistributedCacheServiceInstance

Host not found when issuing Remove command above

$SPFarm = Get-SPFarm
$cacheClusterName = "SPDistributedCacheCluster_" + $SPFarm.Id.ToString() 
$cacheClusterManager = [Microsoft.SharePoint.DistributedCaching.Utilities.SPDistributedCacheClusterInfoManager]::Local 
$cacheClusterInfo = $cacheClusterManager.GetSPDistributedCacheClusterInfo($cacheClusterName); 
$instanceName ="SPDistributedCacheService Name=AppFabricCachingService"
$serviceInstance = Get-SPServiceInstance | ? {($_.Service.Tostring()) -eq $instanceName -and ($_.Server.Name) -eq $env:computername}  
$serviceInstance.Delete()

Add a server and Start Distributed Cache service

Add-SPDistributedCacheServiceInstance

Stop distributed cache service instance

$instanceName ="SPDistributedCacheService Name=AppFabricCachingService"
$serviceInstance = Get-SPServiceInstance | ? {($_.service.tostring()) -eq $instanceName -and ($_.server.name) -eq $env:computername}
$serviceInstance.Unprovision()

Start distributed cache service instance

$instanceName ="SPDistributedCacheService Name=AppFabricCachingService"
$serviceInstance = Get-SPServiceInstance | ? {($_.service.tostring()) -eq $instanceName -and ($_.server.name) -eq $env:computername}
$serviceInstance.Provision()

Add cache

New-Cache <CacheName>

Set timetolive cache data

Stop-CacheCluster
Set-CacheConfig -CacheName <cachename> -TimeToLiveMins 20
Start-CacheCluster

Remove cache

Remove-Cache <CacheName>

Get all cache available

Get-Cache | select CacheName

Get cache statistic

Get-CacheStatistics <cachename>

Tuesday, 25 November 2014

Deploy dll to GAC on Win2k8 and Win2012

I had a requirement where I had to deploy a bug fix which was a simple dll into GAC on production server. The problem came when there wasn't gacutil tools available on that server. So I went to my development server and copied those files over to production. But from which folder?
Mine was from "C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin". There I found folder called NETFX 4.0 Tools. Then I copied all files from that folder to production server and ran it from there.
This has been tested on Windows 2008 R2 and Windows 2012.

Thursday, 20 November 2014

Control lost its state (viewstate) during postback

I want to share my experience during deployment of a new custom application which was develop on top of SharePoint Server 2013. The application was an upgrade version of existing application which had been run well under SharePoint 2007. Long story short the application has been upgraded and verified. I installed this application under SharePoint Server 2013 which act as application server and WFE (server on the cloud), and I joined to another server which has much bigger memory capacity (physical server) which also act as application and WFE. That server also has Project Server 2013 installed, both server has been upgraded to SharePoint and Project Server 2013 SP1.
The next day when users started to use that application, I received many email from users that they couldn't submit theirs request because they have experienced error (looking at ULS it was nullreferenceexception). Looking at trace information that exception was come from a method that take it's value from aspx dropdownlist control. I checked the code and didn't find anything that could related to this error. I asked user to provide me with screen capture before and after the error. To my surprise all aspx web controls has been lost its value during postback. dropdownlist become empty, label become empty and all aspx web controls was lost it's state during postback.
I spent 3 days to figure out what could happen, and that error didn't happen to anyone and happened randomly not just on some button click. During that time I had also noticed that the memory server was utilized at 96-98 percent (this was 16GB server on the cloud). Since this was farm installation, I stopped distributed cache and project server app services on that server. I tested that application with this configuration and the lost control state was still happened. Then I tried accessing that application from another WFE which has twice bigger memory. It was running well without that error.
After 2 weeks of investigation I discovered that the problem came from distributed cache, It looks like aspx or SharePoint store it's viewstate on that distributed cache, and when application trying to get its state back that information got lost during transport from distributed cache server to my application. Network latency between those server hasn't been good during peak hours and using ping command it's sometimes display Request time out. SharePoint default timeout request cache information from distributed cache was set at 20ms. Which was very narrow gap, so I increased that timeout to 80ms. I've also removed distributed cache service from that server.

This blog pointing some got guide on how to troubleshoot this error.

Thursday, 21 November 2013

Workflow got suspended in sharepoint 2013 document library

Uncheck option "Automatically update the workflow status to the current stage name" in sharepoint designer and try again

Also make sure you have register the workflow to the site you are deploying

Another thing you can try is, let SP timer job runs at night.  And try to run workflow again tomorrow.

ref: http://support.microsoft.com/kb/2836896

Unable to register-spworkflow

when I attempted to register workflow using command Register-SPWorkflowService –SPSite http://sharepointsite –WorkflowHostUri https://sharepointsite.domain.com:12290.  I received error http 403 forbidden.
The step that I did to resolve it:
  • I checked that automatically detect proxy has been turned off and add exception to https://sharepointsite.domain.com:12290 in proxy setting (for this to work you need to set this in internet option under system account login) it's better if you could setting the proxy to redirect every request that goes to https://sharepointsite.domain.com to this sharepointsite server
  • I also make sure that proxy has been turned off in internet options from account that run workflow service
  • make sure that windows TCP/IP redirect sharepointsite to 127.0.0.1 (using hosts file configuration)
  • Make sure that workflow account you register is present under User Profile Services. If it doesn't, try add it manually
  • Also make sure that the user which execute register-spworkflow command has access to sharepointsite
This was installed in single server (web, app & workflow).

Wednesday, 5 December 2012

Make add/edit/view custom form and custom SaveButton


Suppose we want to develop web application on the sharepoint 2010.  But the requirement to design form need customization.
To accomplish this there are 2 options (that i know of) that we can do:
  1. Use formtemplate
  2. Create aspx page with page content master from sharepoint
 
Here, I'm going to explain how to customize form using formtemplate:
  1. Open Visual Studio 2010
  2. Create new Sharepoint project (Sharepoint 2010 -> Empty SharePoint Project)
  1. On the next page, enter Uri from site we want to add.  In my example i used: http://mlpt-sp/my/personal/testingground
  2. Select Deploy as a farm solution because we're going to use ascx and place it in ControlTemplate folder
  1. After project has been loaded, next we're going to create content type.  Left click on your project name (SharePointProject1) -> Add -> New Item -> click on Content Type -> give it a name and then click Add
  1. Choose base content type you want to create.  Since I'm going to create this content type for custom list, i picked Item.  Click Finish
  1. Open file Elements.xml, delete  Inherits="TRUE" and add the following xml after tag </FieldRefs>
<XmlDocuments>
 <XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
  <FormTemplates xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
   <Display>CustomFormTemplates</Display>
   <Edit>CustomFormTemplates</Edit>
   <New>CustomFormTemplates</New>
  </FormTemplates>
 </XmlDocument>
</XmlDocuments>
  1. The name CustomFormTemplates will became id for RenderingTemplate in ascx, This was the result from that Elements.xml
  1. When you have finished editing the file Elements.xml we need to add a new ascx that will become the template for Add / Edit / View later. Right click on project name -> Add -> New Item -> select the User Control -> you can name it anything (in the example I used UserControl1.ascx) and click Add
  1. on file UserControl1.ascx paste the following html at the bottom
<%@ Register TagPrefix="wssuc" TagName="ToolBar" src="~/_controltemplates/ToolBar.ascx" %>
<SharePoint:RenderingTemplate ID="CustomFormTemplates" runat="server">
 <Template>
  <span id='part1'>
   <SharePoint:InformationBar ID="InformationBar1" runat="server" />
   <div id="listFormToolBarTop">
    <wssuc:ToolBar CssClass="ms-formtoolbar" ID="toolBarTbltop" RightButtonSeparator="&amp;#160;" runat="server">
     <Template_RightButtons>
      <SharePoint:NextPageButton ID="NextPageButton1"runat="server"/>
      <SharePoint:SaveButton ID="SaveButton1"runat="server"/>
      <SharePoint:GoBackButton ID="GoBackButton1"runat="server"/>
     </Template_RightButtons>
    </wssuc:ToolBar>
   </div>
   <SharePoint:FormToolBar ID="FormToolBar1" runat="server" />
   <SharePoint:ItemValidationFailedMessage ID="ItemValidationFailedMessage1"runat="server"/>
   <table class="ms-formtable" style="margin-top: 8px;" border="0" cellpadding="0" cellspacing="0" width="100%">
    <SharePoint:FolderFormFields ID="FolderFormFields1" runat="server"/>
    <h2>Custom Form Template</h2>
    <SharePoint:FormComponent ID="FormComponent1" TemplateName="AttachmentRows" runat="server" />
   </table>
   <table cellpadding="0" cellspacing="0" width="100%">
    <tr>
     <td class="ms-formline">
      <img src="/_layouts/images/blank.gif" width='1' height='1' alt="" />
     </td>
    </tr>
   </table>
   <table cellpadding="0" cellspacing="0" width="100%" style="padding-top: 7px">
    <tr>
     <td width="100%">
      <SharePoint:ItemHiddenVersion ID="ItemHiddenVersion1"runat="server"/>
      <SharePoint:ParentInformationFieldID="ParentInformationField1"runat="server"/>
      <wssuc:ToolBar CssClass="ms-formtoolbar"ID="toolBarTbl"RightButtonSeparator="&amp;#160;" runat="server">
       <Template_Buttons>
        <SharePoint:CreatedModifiedInfoID="CreatedModifiedInfo1"runat="server"/>
       </Template_Buttons>
       <Template_RightButtons>
        <SharePoint:SaveButton ID="SaveButton2"runat="server"/>
        <SharePoint:GoBackButton ID="GoBackButton2"runat="server"/>
       </Template_RightButtons>
      </wssuc:ToolBar>
     </td>
    </tr>
   </table>
  </span>
  <SharePoint:AttachmentUpload ID="AttachmentUpload1" runat="server"/>
 </Template>
</SharePoint:RenderingTemplate>
  1. Move file UserControl1.ascx from folder SharePointProject1 to ControlTemplates
  2. Now we need to create WebControl for SaveButton. right click on project name -> Add -> New Item -> under installed templates click Code -> give this class a name CustomSaveButton-> click Add
  3. On file CustomSaveButton.cs change this class access to Public with by adding the word in front of the word class,  we alse need to inherits this class from Microsoft.SharePoint.WebControls.SaveButton
  4. Override method SaveItem which is available under inherits class. Here we can add any custom code that we would like.
  1. Back to file UserControl1.ascx here we're going to change default SaveButton with SaveButton that we've created before. Add this tagprefix in above.
<%@ Register Assembly="$SharePoint.Project.AssemblyFullName$" Namespace="SharePointProject1" TagPrefix="cusa" %>
  1. Change <SharePoint:SaveButton to <cusa:CustomSaveButton so it becomes like this
<cusa:CustomSaveButton ID="SaveButton1" runat="server" />
  1. Set trust level in sharepoint site target to Full
  2. Deploy ours solution by right clicking on Project Name (SharePointProject1) -> clik Deploy
  3. Run iisreset
  4. Let's try this by creating a new Custom List and set this list to use other content type, from menu List Settings -> Advance Settings -> Allow management of content types, select yes -> then click on OK
  5. Back to menu List Settings klik Add from existing site content type pick content type that we've already made, mine was SharePointProject1 – CustomFormWithSaveButton
  1. Let's try this custom form with clicking on the New Item then click on the content type that we've created before
After the save button got clicked:
If the form still showing the orginal one, try again the steps above.
If the toolbar got disabled, look for the error message in event viewer

How to get ProjectUID inside Project server workflow

Using this method I was able to extract ProjectUID from workflowProperties.initiationdata
 
Microsoft.Office.Project.Server.Library
 
ProjectWorkflowContext pwc = ProjectWorkflowContext.ParseXml(workflowProperties.InitiationData);
_projectUID = pwc.ProjectUid;